Maison > Article > interface Web > Processus de base du cross-domain ajax
1. AJAX
AJAX (Asynchronous JavaScript and XML), ce qui signifie utiliser JavaScript pour effectuer des requêtes réseau asynchrones.
Le cross-domain peut être réalisé principalement en mettant en place un serveur proxy, JSONP et CORS.
Écrire un code AJAX complet en JavaScript n'est pas compliqué, mais il faut faire attention : les requêtes AJAX sont exécutées de manière asynchrone, c'est-à-dire pour dire, vous devez obtenir la réponse via la fonction de rappel.
Recommandations associées : "vidéo python"
Le processus de création d'ajax est généralement le suivant :
Créez un objet XMLHttpRequest, c'est-à-dire créez un objet d'appel asynchrone ; déterminez les attributs de l'objet XHR ; créez une nouvelle requête HTTP et spécifiez la méthode, l'URL et les informations de vérification de la requête HTTP pour définir une fonction ; répondre aux changements d'état de la requête HTTP ; envoyer la requête HTTP ; obtenir les données renvoyées par l'appel asynchrone ; utiliser JavaScript et DOM pour implémenter une actualisation partielle.
Code.
var xmlhttp;function createXMLHttpRequest () { xmlhttp = null; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else if (window.ActiveXObject) { xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } // 异步调用服务器段数据 if (xmlhttp != null) { // 创建http请求 xmlhttp.open('GET/POST', url, true); // 设置http请求状态变化的函数 xmlhttp.onreadystatechange = httpStateChange; // 发送请求 xmlhttp.send(null); } else { console.log('不支持XHR'); } } // 响应HTTP请求状态变化的函数function httpStateChange () { //判断异步调用是否完成 if (xmlhttp.readyState == 4) {//readyState==4表示后台处理完成了 if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status == 304){ //判断异步调用是否成功,如果成功开始局部更新数据 //code... } else{ console.log("出错状态码:" + xmlhttp.status + "出错信息:" + xmlhttp.statusText); } } }
Pour les versions inférieures d'IE, vous devez passer à un objet ActiveXObject Si vous souhaitez mélanger l'écriture standard et l'écriture IE, vous pouvez l'écrire comme ceci.
var request;if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else { request = new ActiveXObject('Microsoft.XMLHTTP'); }
Déterminez si le navigateur prend en charge le standard XMLHttpRequest en détectant si l'objet fenêtre possède un attribut XMLHttpRequest. Notez que n'utilisez pas le navigator.userAgent du navigateur pour détecter si le navigateur prend en charge une certaine fonctionnalité JavaScript. Premièrement, la chaîne elle-même peut être falsifiée, et deuxièmement, il sera très compliqué de juger la fonctionnalité JavaScript via la version IE.
Après avoir créé l'objet XMLHttpRequest, vous devez d'abord définir la fonction de rappel de onreadystatechange
. Dans la fonction de rappel, il suffit généralement de juger si la demande est terminée via readyState === 4. Si elle est terminée, jugez s'il s'agit d'une réponse réussie en fonction du statut.
La méthode open() de l'objet XMLHttpRequest a 3 paramètres. Le premier paramètre spécifie s'il s'agit de GET ou de POST, le deuxième paramètre spécifie l'adresse URL et le troisième paramètre spécifie s'il faut utiliser l'asynchrone. c'est vrai, donc pas besoin d'écrire. Attention, ne spécifiez jamais le troisième paramètre comme faux, sinon le navigateur cessera de répondre jusqu'à ce que la requête AJAX soit terminée. Si cette demande prend 10 secondes, vous constaterez dans les 10 secondes que le navigateur est dans un état de « mort suspendue ».
Enfin, la méthode send() est appelée pour envoyer réellement la requête. Les requêtes GET ne nécessitent pas de paramètres et les requêtes POST nécessitent que la partie du corps soit transmise sous forme de chaîne ou d'objet FormData.
2. Restrictions de sécurité inter-domaines
En raison de la « même politique d'origine » du navigateur, si le protocole, le nom de domaine et le numéro de port sont différents, l'accès ne sera pas possible. AJAX lui-même ne peut pas traverser de domaines. AJAX demande directement des fichiers ordinaires, ce qui pose le problème de l'accès entre domaines sans autorisation. Cependant, tant qu'il s'agit d'une requête entre domaines, il peut traverser des domaines avec la coopération de. le back-end.
Étant donné que la politique de même origine restreint les navigateurs mais ne restreint pas les serveurs, les serveurs peuvent traverser les domaines.
Est-ce parce que JavaScript ne peut pas demander d'URL à des domaines externes (c'est-à-dire d'autres sites Web) ? Il existe encore des méthodes, probablement les suivantes.
2.1 CORS
CORS (Cross-Origin Resource Sharing, cross-origin Resource Sharing) est une ébauche du W3C qui définit la navigation lorsque les ressources inter-domaines doivent être accédées . Comment le serveur doit-il communiquer avec le serveur.
L'idée de base derrière CORS est d'utiliser des en-têtes HTTP personnalisés pour permettre au navigateur de communiquer avec le serveur afin de déterminer si la requête ou la réponse doit réussir ou échouer.
Par exemple, une simple requête envoyée via GET ou POST n'a pas d'en-tête personnalisé et le contenu principal est texte/plain. Lors de l'envoi de cette demande, vous devez y attacher un en-tête Origin supplémentaire, qui contient les informations source de la page demandée (protocole, nom de domaine et port) afin que le serveur puisse décider de répondre en fonction de ces informations d'en-tête. Vous trouverez ci-dessous un exemple de l’en-tête Origin.
Origin: http://www.nczonline.net
Si le serveur pense que la requête est acceptable, il renverra les mêmes informations source dans l'en-tête Access-Control-Allow-Origin (s'il s'agit d'une ressource publique, il peut renvoyer '*' ). Par exemple :
Access-Control-Allow-Origin: http://www.nczonline.net
S'il n'y a pas un tel en-tête, ou s'il existe cet en-tête mais que les informations source ne correspondent pas, le navigateur rejettera la demande. Normalement, le navigateur gère la demande. Notez que ni la demande ni la réponse ne contiennent d'informations sur les cookies.
Actuellement, tous les navigateurs prennent en charge cette fonction et le navigateur IE ne peut pas être inférieur à IE10. L'ensemble du processus de communication CORS est automatiquement complété par le navigateur et ne nécessite pas la participation de l'utilisateur. Pour les développeurs, il n'y a aucune différence entre la communication CORS et la communication AJAX provenant de la même source, et le code est exactement le même. Une fois que le navigateur découvre que la requête AJAX est d'origine croisée, il ajoutera automatiquement des informations d'en-tête supplémentaires, et parfois une requête supplémentaire sera effectuée, mais l'utilisateur ne la ressentira pas.
Par conséquent, la clé pour parvenir à la communication CORS est le serveur. Tant que le serveur implémente l'interface CORS, la communication entre origines est possible.
Les requêtes ajax habituelles peuvent ressembler à ceci :
<script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("POST", "/damonare",true); xhr.send();</script>
La partie démonare ci-dessus est un chemin relatif Si nous voulons utiliser CORS, le code Ajax pertinent peut ressembler à ceci :
<script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true); xhr.send();</script>.
La différence entre le code et le précédent est que le chemin relatif est remplacé par le chemin absolu des autres domaines, qui est l'adresse d'interface à laquelle vous souhaitez accéder entre les domaines.
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
2.2 图像Ping
我们知道,一个网页可以从任何网页中加载图像,不用担心跨域不跨域。这也是在线广告跟踪浏览量的主要方式。我们也可以动态的创建图像,使用它们的onload和onerror事件处理成西来确定是否接收到了响应。
动态创建图像经常用于图像Ping。
图像Ping是与服务器进行简单、单向的跨域通信的一种方式。请求的数据是通过查询字符串形式发送的,而响应可以是任意内容,但通常是像素图或204响应。通过图像Ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,它能知道响应是什么时候收到的。
来看下面的例子。
var img = new Image(); img.onload = img.onerror = function () { console.log('Done'); }; img.src = 'http://www.example.com/test?name=Nico';
这里创建了一个Image的实例,然后将onload和onerror事件处理程序指定为同一个函数。这样无论是什么响应,只要请求完成,就能得到通知。请求从设置src属性那一刻开始,而这个例子在请求中发送了一个name参数。
图像Ping最常用于跟踪用户点击页面或动态广告曝光次数。
图像Ping有两个主要的缺点:
只能发送GET请求。无法访问服务器的响应文本。
因此,图像Ping只能用于浏览器与服务器间的单向通信。
2.3 JSONP
JSONP是JSON with padding(填充式JSON或参数式JSON)的简写,是应用JSON的一种新方法。JSONP与JSON看起来差不多,只不过是被包含在函数调用中的JSON,如下。
callback({'name': 'Azure'});
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的,而数据就是传入回调参数中JSON数据。下面是一个典型的JSONP请求。
http://freegeoip.net/json/?callback=handleResponse
这个URL是在请求一个JSONP地理定位服务。通过查询字符串来指定JSONP服务的回调参数是很常见的,就像上面的URL所示,这里指定的回调函数的名字叫handleResponse()。
JSONP是通过动态3f1c4e4b6b16bbbd69b2ee476dc4f83a元素来使用的,使用时可以为src属性指定一个跨域URL。
这里的fa606c102b26eb7f8e8a6d6e20193568元素与a1f02c36ba31691bcfe87b2722de723b元素类似,都有能力不受限制的从其他域加载资源。因为JSONP是有效的JS代码,所以在请求完成后,即在JSONP响应加载到页面中以后,就会立即执行。来看一个例子。
function handleResponse (response) { console.log('u r at IP address ' + response.ip + ', which is in ' + response.city + ', ' + response.region_name); } var script = document.createElement('script'); script.src = 'http://freegeoip.net/json/?callback=handleResponse'; document.body.insertBefore(script, document.body.firstChild);
这个例子通过查询地理定位服务来显示IP地址和地理位置信息。
JSONP之所以在开发人员中极为流行,主要原因是它非常简单易用。与图像Ping相比,它的优点在于能够直接访问响应文本,支持在浏览器与服务器之间双向通信。不过,JSONP也有两点不足。
首先,安全性问题。JSONP是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了完全放弃JSONP调用之外,没有办法追究。因此在使用不是自己运维的Web服务时,一定得保证它安全可靠。
其次,要确定JSONP请求是否失败并不容易。
CORS和JSONP对比
JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。SONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。
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!