Maison  >  Article  >  interface Web  >  La solution parfaite au problème inter-domaines ajax

La solution parfaite au problème inter-domaines ajax

php中世界最好的语言
php中世界最好的语言original
2018-04-24 16:23:152634parcourir

Cette fois, je vais vous apporter la solution parfaite au problème inter-domaines ajax. Quelles sont les précautions pour résoudre le problème inter-domaines ajax. Voici des cas réels, jetons un coup d'œil.

Aujourd'hui, je vais enregistrer quelques problèmes concernant le cross-domain ajax. Juste en cas d'urgence.

Interdomaine

Restrictions de la politique d'origine

La politique d'origine empêche les scripts chargés à partir d'un domaine d'être obtenus ou manipulés Document propriétés sur un autre domaine. Autrement dit, le domaine de l'URL demandée doit être le même que le domaine de la page Web actuelle. Cela signifie que le navigateur isole le contenu de différentes sources pour empêcher les opérations entre elles.

Solution

De manière générale, il existe deux manières courantes, l'une du côté serveur, l'autre du point de vue du client Partez. Les deux présentent des avantages et des inconvénients, et la méthode à utiliser nécessite une analyse spécifique.

  1. Le serveur définit l'en-tête de réponse

  2. Le serveur proxy

  3. Le client utilise un script mécanisme de rappel.

Méthode 1

Le mot-clé Access-Control-Allow-Origin
ne prendra effet que s'il est défini côté serveur . Autrement dit, même si vous utilisez

xmlhttprequest.setHeaderREquest('xx','xx');
sur le client, cela n'aura aucun effet.

Requête ajax normale

Simulons le cas d'implémentation d'une requête ajax non interdomaine.

test1.html

nbsp;html>


 <meta>
 <title>ajax 测试</title>


<input>
<p></p>
<script>
 var xhr = new XMLHttpRequest();
 var url = &#39;http://localhost/learn/ajax/test1.php&#39;;
 function crossDomainRequest() {
  document.getElementById(&#39;content&#39;).innerHTML = "<font color=&#39;red&#39;>loading...";
  // 延迟执行
  setTimeout(function () {
   if (xhr) {
    xhr.open(&#39;GEt&#39;, url, true);
    xhr.onreadystatechange = handle_response;
    xhr.send(null);
   } else {
    document.getElementById(&#39;content&#39;).innerText = "不能创建XMLHttpRequest对象";
   }
  }, 3000);
 }
 function handle_response() {
  var container = document.getElementById(&#39;content&#39;);
  if (xhr.readyState == 4) {
   if (xhr.status == 200 || xhr.status == 304) {
    container.innerHTML = xhr.responseText;
   } else {
    container.innerText = &#39;不能跨域请求&#39;;
   }
  }
 }
</script>

Le contenu de test1.PHP dans le même répertoire est le suivant :

<?php echo "It Works.";
?>

La solution parfaite au problème inter-domaines ajax

Requête inter-domaines

Tout à l'heure, le fichier HTML et le fichier PHP étaient tous deux sous le conteneur Apache, il n'y avait donc pas de situation inter-domaines. Maintenant, placez le fichier HTML sur le bureau. et demandez à nouveau les données PHP. Cela crée une telle "requête inter-domaines".

Faites attention aux informations de la barre d'adresse du navigateur

Lors de votre nouvelle visite, vous trouverez le message d'erreur suivant.

La solution parfaite au problème inter-domaines ajax

Dans ce cas, une opération courante consiste à définir Access-Control-Allow-Origin.

Format : Access-Control-Allow-Origin : domain.com/xx/yy.*

Si vous connaissez le nom de domaine du client ou le chemin fixe de la demande, il est préférable de ne pas utiliser la méthode des caractères génériques pour garantir davantage la sécurité. Si vous n'êtes pas sûr, utilisez simplement le caractère générique *.

Lorsque le langage de développement back-end est PHP, vous pouvez le définir comme ceci au début du fichier :

header("Access-Control-Allow-Origin: *");
S'il s'agit d'une page ASPX, vous devez le définir comme ceci (Java est similaire) :

Response.AddHeader("Access-Control-Allow-Origin", "*");
À ce moment-là, visitez à nouveau le chemin tout à l'heure.

La solution parfaite au problème inter-domaines ajax

ServeurMode proxy

Cette méthode devrait être considérée comme plus couramment utilisée et largement adoptée à sens unique. Dire qu’être agent, c’est un peu trop écrit, mais en fait, ce n’est qu’un messager. Donnons un petit exemple :

Xiao Ming aime une fille nommée Xiaohong en classe 3, mais est trop gênée pour lui demander son QQ et son identifiant WeChat. Ensuite, j'ai demandé à Xiaolan, une fille de ma classe. Venez vous aider à l'obtenir. Xiaolan équivaut donc à un agent. Aidez Xiao Ming à obtenir les coordonnées de Xiao Hong qui n'ont pas pu être obtenues directement.

Donnons un exemple pour illustrer ce problème.

Demande inter-domaines directe

Modifiez simplement l'URL tout de suite et laissez ajax demander directement des données à d'autres sites Web.

nbsp;html>


 <meta>
 <title>ajax 测试</title>


<input>
<p></p>
<script>
 var xhr = new XMLHttpRequest();
// var url = &#39;http://localhost/learn/ajax/test1.php&#39;;
  var url = &#39;http://api.qingyunke.com/api.php?key=free&appid=0&msg=%E5%93%92%E5%93%92&#39;;
 function crossDomainRequest() {
  document.getElementById(&#39;content&#39;).innerHTML = "<font color=&#39;red&#39;>loading...";
  // 延迟执行
  setTimeout(function () {
   if (xhr) {
    xhr.open(&#39;GEt&#39;, url, true);
    xhr.onreadystatechange = handle_response;
    xhr.send(null);
   } else {
    document.getElementById(&#39;content&#39;).innerText = "不能创建XMLHttpRequest对象";
   }
  }, 3000);
 }
 function handle_response() {
  var container = document.getElementById(&#39;content&#39;);
  if (xhr.readyState == 4) {
   if (xhr.status == 200 || xhr.status == 304) {
    container.innerHTML = xhr.responseText;
   } else {
    container.innerText = &#39;不能跨域请求&#39;;
   }
  }
 }
</script>

Les résultats sont les suivants :

La solution parfaite au problème inter-domaines ajax

Activer le mode proxy

Nous utilisons toujours le HTML page tout à l'heure Propre interface :

url = 'http://localhost/learn/ajax/test1.php';

具体如下:

nbsp;html>


 <meta>
 <title>ajax 测试</title>


<input>
<p></p>
<script>
 var xhr = new XMLHttpRequest();
 var url = &#39;http://localhost/learn/ajax/test1.php&#39;;
//  var url = &#39;http://api.qingyunke.com/api.php?key=free&appid=0&msg=%E5%93%92%E5%93%92&#39;;
 function crossDomainRequest() {
  document.getElementById(&#39;content&#39;).innerHTML = "<font color=&#39;red&#39;>loading...";
  // 延迟执行
  setTimeout(function () {
   if (xhr) {
    xhr.open(&#39;GEt&#39;, url, true);
    xhr.onreadystatechange = handle_response;
    xhr.send(null);
   } else {
    document.getElementById(&#39;content&#39;).innerText = "不能创建XMLHttpRequest对象";
   }
  }, 3000);
 }
 function handle_response() {
  var container = document.getElementById(&#39;content&#39;);
  if (xhr.readyState == 4) {
   if (xhr.status == 200 || xhr.status == 304) {
    container.innerHTML = xhr.responseText;
   } else {
    container.innerText = &#39;不能跨域请求&#39;;
   }
  }
 }
</script>

然后对应的test1.php应该帮助我们实现数据请求这个过程,把“小红的联系方式”要到手,并返回给“小明”。

<?php $url = &#39;http://api.qingyunke.com/api.php?key=free&appid=0&msg=hello%20world.&#39;;
$result = file_get_contents($url);
echo $result;
?>

下面看下代码执行的结果。

La solution parfaite au problème inter-domaines ajax

jsonp方式

JSONP(JSON with Padding) 灵感其实源于在HTML页面中script标签内容的加载,对于script的src属性对应的内容,浏览器总是会对其进行加载。于是:

克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。

实现的思路就是:

在服务器端组装出客户端预置好的json数据,通过回调的方式传回给客户端。

原生实现

nbsp;html>


 <meta>
 <title>ajax 测试</title>
 <script></script>


<input>
<input>
<p></p>
<script>
function jsonpcallback(result) {
 for(var i in result) {
  alert(i+":"+result[i]);
 }
 }
 var JSONP = document.createElement("script");
 JSONP.type=&#39;text/javascript&#39;;
 JSONP.src=&#39;http://localhost/learn/ajax/test1.php?callback=jsonpcallback&#39;;
 document.getElementsByTagName(&#39;head&#39;)[0].appendChild(JSONP);
</script>

服务器端test1.php内容如下:

<?php $arr = [1,2,3,4,5,6];
$result = json_encode($arr);
echo "jsonpcallback(".$result.")";
?>

需要注意的是最后组装的返回值内容。

来看下最终的代码执行效果。

La solution parfaite au problème inter-domaines ajax

JQuery方式实现

采用原生的JavaScript需要处理的事情还是蛮多的,下面为了简化操作,决定采用jQuery来代替一下。

nbsp;html>


 <meta>
 <title>ajax 测试</title>
 <script></script>


<input>
<input>
<p></p>
<script>
 function later_action(msg) {
  var element = $("<p><font color=&#39;green&#39;>"+msg+"<br />");
  $("#content").append(element);
 }
 $("#btn").click(function(){
  // alert($("#talk").val());
  $.ajax({
  url: &#39;http://localhost/learn/ajax/test1.php&#39;,
  method: &#39;post&#39;,
  dataType: &#39;jsonp&#39;,
  data: {"talk": $("#talk").val()},
  jsonp: &#39;callback&#39;,
  success: function(callback){
   console.log(callback.content);
   later_action(callback.content);
  },
  error: function(err){
   console.log(JSON.stringify(err));
  },
 });
 });
</script>

相应的,test1.php为了配合客户端聊天的需求,也稍微做了点改变。

<?php $requestparam = isset($_GET[&#39;callback&#39;])?$_GET[&#39;callback&#39;]:&#39;callback&#39;;
// 青云志聊天机器人接口: http://api.qingyunke.com/api.php?key=free&appid=0&msg=hello
// 接收来自客户端的请求内容
$talk = $_REQUEST[&#39;talk&#39;];
$result = file_get_contents("http://api.qingyunke.com/api.php?key=free&appid=0&msg=$talk");
// 拼接一些字符串
echo $requestparam . "($result)";
?>

最后来查看一下跨域的效果吧。

JSONP 跨域实现聊天应用

总结

至此,关于简单的ajax跨域问题,就算是解决的差不多了。对我个人而言,对于这三种方式有一点点自己的看法。

  1. 服务器设置Access-Control-Allow-Origin的方式适合信用度高的小型应用或者个人应用。

  2. 代理模式则比较适合大型应用的处理。但是需要一个统一的规范,这样管理和维护起来都会比较方便。

  3. JSONP方式感觉还是比较鸡肋的(有可能是我经验还不足,没认识到这个方式的优点吧(⊙﹏⊙)b)。自己玩玩知道有这么个东西好了。维护起来实在是优点麻烦。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

详细解析JS中Ajax的使用技巧

JQuery调用Ajax加载图片

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn