方法一:HTML5新的标准中,增加了” Cross-Origin Resource Sharing”特性,这个特性的出现使得跨域通信只需通过配置http协议头来即可解决。
Cross-Origin Resource Sharing 详细解释见:
http://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html
Cross-Origin Resource Sharing实现的最重要的一点就是对参数” Access-Control-Allow-Origin”的配置,即通过 次参数检查该跨域请求是否可以被通过。
如:Access-Control-Allow-Origin:http://a.com表示允许a.com下的域名跨域访问;
Access-Control-Allow-Origin:*表示允许所有的域名跨域访问。
如果需要读取读取cookie:
需要配置参数:Access-Control-Allow-Credentials:true
同时在xhr发起请求的时候设置参数withCredentials为true:
var xhr = new XMLHttpRequest();
xhr.open();
xhr.withCredentials = true; //这个放在xhr.open后面执行,否则有些浏览器部分版本会异常,导致设置无效。
示例代码:
php:
php
1
2
3
4
|
header('Access-Control-Allow-Origin:http: //a.com');
header('Access-Control-Allow-Methods:POST,GET');
header('Access-Control-Allow-Credentials:true');
echo'Cross-domain Ajax';
|
JS:
JavaScript
1
2
3
4
5
6
7
8
9
10
varxhr =newXMLHttpRequest(); ;
xhr.open('GET','http: //b.com/cros/ajax.php',true);
xhr.withCredentials =true;
xhr.onload =function() {
alert(xhr.response);//reposHTML;
};
xhr.onerror =function() {
alert('error making the request.');
};
xhr.send();
方法二:使用postMessage实现Ajax跨域请求
1. postMessage的用法
postMessage是HTML5为解决js跨域问题而引入的新的API,允许多个iframe/window跨域通信。
假设有结构如下:
test.html
- <section id="wrapper">
- <header>
- <h1>postMessage (跨域)</h1>
- </header>
- <article>
- <form>
- <p>
- <label for="message">给iframe发一个信息:</label>
- <input type="text" name="message" value="son" id="message" />
- <input type="submit" />
- </p>
- </form>
- <h4>目标iframe传来的信息:</h4>
- <p id="test">暂无信息</p>
- <iframe id="iframe"
- src="http://xiebiji.com/works/postmessage/iframe.html"></iframe>
- </article>
- </section>
iframe.html
- <strong>iframe指向xiebiji.com</strong>
- <form>
- <p>
- <label for="message">给父窗口发个信息:</label>
- <input type="text" name="message" value="dad" id="message" />
- <input type="submit" />
- </p>
- </form>
- <p id="test">暂无信息。</p>
下面是test.html里的Javascript代码(发送数据):
- var win = document.getElementById("iframe").contentWindow;
- document.querySelector('form').onsubmit=function(e){
- win.postMessage(document.getElementById("message").value,"*");
- if (e.preventDefault)
- e.preventDefault();
- e.returnValue = false;
- }
关键代码就一句:
win.postMessage(document.getElementById("message").value,"*");
postMessage是通信对象的一个方法,所以向iframe通信,就是iframe对象调用postMessage方法。postMessage有两个参数,缺一不可。第一个参数是要传递的数据,第二个参数是允许通信的域,“*”代表不对访问的域进行判断,可理解为允许所有域的通信。
然后是iframe.html里侦听接收数据的代码:
- var parentwin = window.parent;
- window.onmessage=function(e){
- document.getElementById("test").innerHTML = e.origin + "say:" + e.data;
- parentwin.postMessage('HI!你给我发了"<span>'+e.data+'"</span>。',"*");
- };
很简单,相信一看就懂了。e.data包含传送过来的数据,e.origin指代源域。
然后iframe.html也给test.html发送回应的数据,test.html接收数据。代码雷同,就不贴代码了。
点此查看Demo(代码素Joe哥给的)
2. Ajax跨域请求
基于以上的跨域通信,只要将Ajax代码放在iframe.html里的onmessage处理函数里头,将test.html用postMessage传过来的数据作为参数发送请求,再将返回的数据用postMessage传给test.html。这样就实现了跨域的Ajax请求。其实是很简单的东西。
贴个示例代码吧,但跟以上的代码无关。
- (function(){
-
- window.onmessage = function(e){
- var url = "http://yangzebo.com/demo/noforget/test.php?msg=" + e.data;
-
- var xhr = getXHR();
- if(xhr){
- xhr.open("GET",url,true);
- xhr.onreadystatechange = changeHandle;
- xhr.send(null);
- }else{
- alert("不支持Ajax");
- }
- function changeHandle(){
- if(xhr.readyState == 4){
- var parentwin = window.parent;
- parentwin.postMessage(xhr.responseText,"*");
- }
- }
- function getXHR(){
- var xhr_temp;
- if(window.XMLHttpRequest){
- xhr_temp = new XMLHttpRequest();
- }else if(window.ActiveXObject){
- xhr_temp = new ActiveXObject("Microsoft.XMLHTTP");
- }else{
- xhr_temp = null;
- }
- return xhr_temp;
- }
- };
- })();