Heim  >  Artikel  >  Web-Frontend  >  Die perfekte Lösung für das domänenübergreifende Ajax-Problem

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

php中世界最好的语言
php中世界最好的语言Original
2018-04-24 16:23:152680Durchsuche

Dieses Mal werde ich Ihnen die perfekte Lösung für das domänenübergreifende Ajax-Problem vorstellen. Was sind die Vorsichtsmaßnahmen zur Lösung des domänenübergreifenden Ajax-Problems?

Heute werde ich einige Probleme mit Ajax Cross-Domain aufzeichnen. Nur für den Notfall.

Domänenübergreifend

Ursprüngliche Richtlinieneinschränkungen

Die ursprüngliche Richtlinie verhindert, dass aus einer Domäne geladene Skripte abgerufen oder manipuliert werden. Dokument Eigenschaften auf einer anderen Domain. Das heißt, die Domäne der angeforderten URL muss mit der Domäne der aktuellen Webseite übereinstimmen. Das bedeutet, dass der Browser Inhalte aus verschiedenen Quellen isoliert, um Vorgänge zwischen ihnen zu verhindern.

Lösung

Im Allgemeinen gibt es zwei gängige Methoden: eine von der Serverseite und eine von der Client-Perspektive. Beide haben Vor- und Nachteile, und welche Methode verwendet werden soll, erfordert eine spezifische Analyse.

  1. Der Server legt den Antwortheader fest

  2. Der Server-Proxy

  3. Der Client verwendet ein Skript Rückrufmechanismus.

Methode 1

Das Schlüsselwort Access-Control-Allow-Origin
wird nur dann wirksam, wenn es auf der Serverseite festgelegt ist . Mit anderen Worten: Selbst wenn Sie

xmlhttprequest.setHeaderREquest('xx','xx');
auf dem Client verwenden, hat dies keine Wirkung.

Normale Ajax-Anfrage

Lassen Sie uns die Fallimplementierung einer nicht-domänenübergreifenden Ajax-Anfrage simulieren.

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>

Der Inhalt von test1.PHP im selben Verzeichnis lautet wie folgt:

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

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

Kreuz -Domain-Anfrage

Im Moment befanden sich sowohl die HTML-Datei als auch die PHP-Datei im Apache-Container, sodass es keine domänenübergreifende Situation gab. Legen Sie nun die HTML-Datei auf den Desktop und fordern Sie PHP an Daten erneut und erstellt so etwas wie eine „domänenübergreifende Anfrage“.

Achten Sie auf die Adressleisteninformationen des Browsers

Beim erneuten Besuch finden Sie die folgende Fehlermeldung.

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

In diesem Fall besteht eine übliche Operation darin, Access-Control-Allow-Origin festzulegen.

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

Wenn Sie den Domänennamen des Clients oder den festen Pfad der Anfrage kennen, sollten Sie dies am besten nicht tun Verwenden Sie die Wildcard-Methode, um die Sicherheit weiter zu gewährleisten. Wenn Sie sich nicht sicher sind, verwenden Sie einfach das Platzhalterzeichen *.

Wenn die Back-End-Entwicklungssprache PHP ist, können Sie sie am Anfang der Datei wie folgt festlegen:

header("Access-Control-Allow-Origin: *");
Wenn es sich um eine ASPX-Seite handelt, müssen Sie sie wie folgt festlegen (Java ist ähnlich):

Response.AddHeader("Access-Control-Allow-Origin", "*");
Besuchen Sie zu diesem Zeitpunkt den Pfad gerade noch einmal.

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

ServerProxy-Modus

Diese Methode sollte als häufiger verwendet und weit verbreitet angesehen werden. Eine Möglichkeit. Zu sagen, dass der Beruf eines Agenten etwas übertrieben ist, ist in Wirklichkeit nur ein Bote. Geben wir ein kleines Beispiel:

Xiao Ming mag ein Mädchen namens Xiao Hong in der 3. Klasse, ist aber zu verlegen, um nach ihrem QQ und ihrer WeChat-ID zu fragen. Dann fragte ich Xiaolan, ein Mädchen aus meiner Klasse. Kommen Sie und helfen Sie sich, es zu bekommen. Xiaolan ist also gleichbedeutend mit einem Agenten. Helfen Sie Xiao Ming, die Kontaktinformationen von Xiao Hong zu erhalten, die nicht direkt erhalten werden konnten.

Lassen Sie uns ein Beispiel geben, um dieses Problem zu veranschaulichen.

Direkte domänenübergreifende Anfrage

Ändern Sie einfach die URL und lassen Sie Ajax Daten direkt von anderen Websites anfordern.

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>

Die Ergebnisse sind wie folgt:

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

Proxy-Modus aktivieren

Für die HTML-Seite gerade: Wir verwenden immer noch unsere eigene Schnittstelle:

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;
?>

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

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

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.")";
?>

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

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

Die perfekte Lösung für das domänenübergreifende Ajax-Problem

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加载图片

Das obige ist der detaillierte Inhalt vonDie perfekte Lösung für das domänenübergreifende Ajax-Problem. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn