Maison  >  Article  >  interface Web  >  Plusieurs méthodes inter-domaines en Javascript

Plusieurs méthodes inter-domaines en Javascript

高洛峰
高洛峰original
2017-02-28 14:35:291163parcourir

Dans les langages de programmation côté client tels que JavaScript, la politique de même origine stipule que les scripts inter-domaines sont isolés. Les scripts d'un domaine ne peuvent pas accéder et exploiter la plupart des propriétés et méthodes d'un autre domaine. Ce n'est que lorsque deux domaines ont le même protocole, le même hôte et le même port que nous les considérons comme étant le même domaine. Cependant, dans le développement réel, nous avons souvent besoin d'obtenir des ressources d'autres domaines. À l'heure actuelle, diverses méthodes de ressources inter-domaines entrent en jeu. Aujourd'hui, nous résumerons principalement plusieurs méthodes inter-domaines couramment utilisées dans le travail de requête.

1.window.name

L'attribut name de l'objet window est un attribut très spécial Lorsqu'une nouvelle page est chargée dans le cadre, la valeur de l'attribut name reste inchangée. Ensuite, nous pouvons utiliser iframe dans la page A pour charger la page B d'autres domaines et utiliser JavaScript dans la page B pour attribuer les données à transmettre à window.name Une fois l'iframe chargée, la valeur de l'attribut name peut être obtenue pour y accéder. Informations envoyées par le service web. Mais l’attribut name n’est accessible qu’aux frames portant le même nom de domaine. Cela signifie que pour accéder à l'attribut name, lorsque la page du service Web distant est chargée, le cadre doit être ramené au domaine d'origine. Autrement dit, la page A modifie l'adresse de l'iframe et la remplace par une adresse dans le même domaine, puis la valeur de window.name peut être lue. Une fois la propriété name obtenue, détruisez le cadre. Cette méthode est très adaptée aux demandes de données unidirectionnelles et le protocole est simple et sûr.

Le code de la page B (www.jesse.com/data.html) est le suivant :

<script type="text/javascript">
window.name = 'I was there!';
// 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右
// 数据格式可以自定义,如json、字符串
</script>

Page A ( www.jack.com/index.html) Le code est le suivant :

<script type="text/javascript">
var state = 0,
  iframe = document.createElement('iframe'),
  loadfn = function() {
    if (state === 1) {
      var data = iframe.contentWindow.name; // 读取数据
      console.log(data); //弹出'I wasthere!'
      (function(){
        //获取数据以后销毁这个iframe。
        iframe.contentWindow.document.write('');
        iframe.contentWindow.close();
        document.body.removeChild(iframe);
      })();
    } else if (state === 0) {
      state = 1;
      // 设置的代理页面使其回原始域
      iframe.contentWindow.location = "http://www.jack.com/proxy.html"; 
    }
  };
iframe.src = 'http://www.jesse.com/data.html';
if (iframe.attachEvent) {
  iframe.attachEvent('onload', loadfn);
} else {
  iframe.onload = loadfn;
}
document.body.appendChild(iframe);
</script>

2. le navigateur interdit par défaut l'accès inter-domaines, mais il n'est pas interdit d'utiliser l'attribut src de la balise dans la page pour référencer des fichiers dans d'autres domaines. Sur cette base, vous pouvez facilement réaliser une communication interdomaine complète en créant des méthodes de nœud avec des attributs src. Il existe plusieurs méthodes cross-domain utilisant ce principe :

Création dynamique de scripts

Par exemple, si je souhaite charger les données du domaine B depuis la page pageA du domaine A, alors sur la page pageB du domaine B Dans cet exemple, je déclare les données requises par pageA sous forme de JavaScript, puis j'utilise la balise script pour charger la pageB dans la pageA, puis le script dans la pageB sera exécuté. Le code de la

pageA(www.jack.com/index.html) est le suivant :

function getData(data){
  //这里是对获取的数据的相关操作
  console.log(data);
  //数据获取到后移除创建的script标签
  document.body.removeChild(originData);
}
var originData = document.createElement('script');
originData.src = 'http://www.jesse.com/data.js';
originData.setAttribute("type", "text/javascript");
document.body.appendChild(originData);

pageB(www.jesse. com/ data.js) le code est le suivant :

getData('这里是远程跨域获取的数据');//数据格式可以自定义,如json、字符串

jsonp

Lors de l'utilisation de $.ajax() pour obtenir des données à distance , s'il s'agit de ressources de domaine, vous pouvez utiliser la méthode jsonp. Je pensais que jsonp était un type d'ajax, mais plus tard j'ai réalisé que ce n'était pas du tout la même chose. Ajax demande des données en mode xhr, tandis que jsonp demande des données en mode script. C'est la même chose que la méthode de création de script dynamique ci-dessus. Le code de la


pageA(www.jack.com/index.html) est le suivant :

$.ajax({
  //JSONP不支持POST方式
  type:"GET",
  url:"http://www.jesse.com/data.php",
  dataType:"jsonp",
  //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
  jsonpCallback:"getData",
  success: function(data){
    console.log(data);
  },
  error: function(){
    console.log('fail');
  }
})

pageB(www .jesse .com/data.js) Le code est le suivant :

<?php
  $callback = $_GET[&#39;callback&#39;];//得到回调函数名,这里是getData
  $data = array(&#39;a&#39;,&#39;b&#39;,&#39;c&#39;);//要返回的数据
  echo $callback.&#39;(&#39;.json_encode($data).&#39;)&#39;;//输出
?>

3.document.domain

est le même pour le domaine principal mais différent pour le sous-domaine. L'exemple peut être résolu en définissant document.domain. La méthode spécifique consiste à ajouter document.domain = "a.com" aux deux fichiers http://www.php.cn/ et http://www.php.cn/ respectivement, puis à transmettre le fichier a.html ; Créez une iframe pour contrôler le contentDocument de l'iframe, afin que les deux fichiers js puissent "interagir". Bien entendu, cette méthode ne peut résoudre que la situation où le domaine principal est le même mais le nom de domaine secondaire est différent


a.html sur www.a.com

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
  var doc = ifr.contentDocument || ifr.contentWindow.document;
  // 在这里操纵b.html
  alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

b.html sur script.a.com

document.domain = 'a.com';

4. (CORS)

Principe : Le partage de ressources d'origine croisée (CORS) définit un mécanisme d'accès inter-domaines qui permet à AJAX d'obtenir un accès inter-domaines. CORS permet à une application Web sur un domaine de soumettre des requêtes AJAX inter-domaines à un autre domaine. La mise en œuvre de cette fonctionnalité est aussi simple que l'envoi d'un en-tête de réponse par le serveur. Il garantit la sécurité des demandes grâce à une déclaration collaborative client-serveur. Le serveur ajoutera une série de paramètres de requête HTTP (tels que Access-Control-Allow-Origin, etc.) à l'en-tête de requête HTTP pour limiter les requêtes de domaine et les types de requêtes pouvant être acceptés, et le client doit déclarer les siens lorsque initier une requête Origin (Origin), sinon le serveur ne la traitera pas. Si le client ne fait pas de déclaration, la requête sera même directement interceptée par le navigateur et n'atteindra pas le serveur. Après avoir reçu la requête HTTP, le serveur comparera les domaines et seules les requêtes du même domaine seront traitées. Le code de la

pageA(www.jack.com/index.html) est le suivant :

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
  if(xhr.readyState === 4 && xhr.status === 200){
    console.log(xhr.responseText);
  }
};
xhr.open("get","http://www.jesse.com/data.php");
xhr.send(null);

pageB(www.jesse. com/ data.php) le code est le suivant :

<?php
  header("Access-Control-Allow-Origin: http://www.php.cn/");//与简单的请求相同
  header("Access-Control-Allow-Methods: GET, POST");//允许请求的方法
  header("Access-Control-Max-Age: 3628800"); //将这个请求缓存多长时间
  $data = array(&#39;a&#39;,&#39;b&#39;,&#39;c&#39;);//要返回的数据
  echo json_encode($data);//输出
?>

5.window.postMesage n'est pas couramment utilisé

window.postMessage Méthode (message,targetOrigin) Il s'agit d'une fonctionnalité nouvellement introduite dans HTML5. Vous pouvez l'utiliser pour envoyer des messages à d'autres objets fenêtre, que l'objet fenêtre appartienne à la même origine ou à des origines différentes, actuellement IE8, FireFox, Chrome, Opera. et d'autres navigateurs prennent déjà en charge la méthode window.postMessage. Le code de la


pageA (www.jack.com/index.html) est le suivant :


<iframe id="proxy" src="http://www.jesse.com/index.html" onload="postMsg()" style="display: none"></iframe>
<script type="text/javascript">
var obj = {
  msg: 'hello world'
}

function postMsg() {
  var iframe = document.getElementById('proxy');
  var win = iframe.contentWindow;
  win.postMessage(obj, 'http://www.jesse.com');
}
</script>

pageB(www.jesse.com/data.php)代码如下:
<script type="text/javascript">
window.onmessage = function(e) {
  console.log(e.data.msg + " from " + e.origin);
}
</script>

6. location.hash n'est pas couramment utilisé

pageA(www.jack.com/index.html) le code est le suivant :

function startRequest() {
  var ifr = document.createElement('iframe');
  ifr.style.display = 'none';
  ifr.src = 'http://www.jesse.com/b.html#sayHi'; //传递的location.hash 
  document.body.appendChild(ifr);
}

function checkHash() {
  try {
    var data = location.hash ? location.hash.substring(1) : '';
    if (console.log) {
      console.log('Now the data is ' + data);
    }
  } catch (e) {};
}
setInterval(checkHash, 5000);
window.onload = startRequest;

pageA(www .jack.com/proxy.html) Le code est le suivant :

parent.parent.location.hash = self.location.hash.substring(1);

pageB (www.jesse.com/ b.html) Le code est le suivant :

function checkHash() {
  var data = '';
  //模拟一个简单的参数处理操作
  switch (location.hash) {
    case '#sayHello':
      data = 'HelloWorld';
      break;
    case '#sayHi':
      data = 'HiWorld';
      break;
    default:
      break;
  }
  data && callBack('#' + data);
}

function callBack(hash) {
  // ie、chrome的安全机制无法修改parent.location.hash,所以要利用一个中间的www.a.com域下的代理iframe
  var proxy = document.createElement('iframe');
  proxy.style.display = 'none';
  proxy.src = 'http://www.jack/c.html' + hash; // 注意该文件在"www.jack.com"域下
  document.body.appendChild(proxy);
}
window.onload = checkHash;

Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'apprentissage de chacun. J'espère également que tout le monde soutiendra le site Web PHP chinois.

Pour plus d'articles liés à plusieurs méthodes multi-domaines de Javascript, veuillez faire attention au site Web PHP 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