AJAX跨域
1 header(‘Access-Control-Allow-Origin:http://localhost:63342‘); 2 echo json_encode($_GET);
1 var xdr = new XDomainRequest(); 2 xdr.open(‘get‘, ‘http://localhost/ajax/data.php?‘+fnGetURLParam({name: ‘hum‘, age: 20})); 3 xdr.send(null); 4 xdr.onload = function(){ 5 console.log(xdr.responseText); 6 } 7 xdr.onerror = function(){ 8 console.log(‘error‘); 9 }
post请求的XDR示例:
1 header(‘Access-Control-Allow-Origin:http://localhost:63342‘); 2 echo json_encode($_POST);
1 var xdr = new XDomainRequest(); 2 // xdr.contentType = "application/X-www-form-urlencoded"; // contentType是只读的(IE8报错IE9不报错但是设置不成功) 3 xdr.open(‘post‘, ‘http://localhost/ajax/data.php‘); 4 xdr.send(fnGetURLParam({name: ‘hum‘, age: 20})); 5 xdr.onload = function(){ 6 console.log(xdr.responseText); // [] 7 console.log(xdr.contentType); // text/html 8 } 9 xdr.onerror = function(){ 10 console.log(‘error‘); 11 }
NOTE:XDR的post请求无法设置请求头Content-Type为application/x-www-form-urnencoded,后端不能获取请求数据。为了兼容IE89不能使用POST方式。
XDR对象的其他方法、事件、属性:
abort方法:在响应前调用来中断请求
1 var xdr = new XDomainRequest(); 2 xdr.open(‘get‘, ‘http://localhost/ajax/data.php?‘+fnGetURLParam({name: ‘hum‘, age: 20})); 3 xdr.send(null); 4 xdr.onload = function(){ 5 console.log(xdr.responseText); // 不会执行 6 } 7 xdr.onerror = function(){ 8 console.log(‘error‘); 9 } 10 xdr.abort(); // 中断请求
NOTE:timeout属性、ontimeout事件可能有些问题。考虑使用jquery的定时器调用abort来模拟超时。XHR对象也可。
1 header(‘Access-Control-Allow-Origin:http://localhost:63342‘); 2 sleep(10); 3 echo json_encode($_GET);
1 var xdr = new XDomainRequest(); 2 xdr.open(‘get‘, ‘http://localhost/ajax/data.php?‘+fnGetURLParam({name: ‘hum‘, age: 20})); 3 xdr.send(null); 4 xdr.onload = function(){ 5 console.log(xdr.responseText); //没有输出 6 } 7 xdr.onerror = function(){ 8 console.log(‘error‘); 9 } 10 setTimeout(function(){ 11 xdr.abort(); 12 }, 1000);
2、标准浏览器对CORS的支持
标准浏览器都对XHR对象实现了对CORS的原生支持。
XHR的CORS跨域,XHR对象可以访问status和同步请求,但是也有一些限制:
不能使用setRequestHeader设置自定义头部信息
不能发送和接受cookie
兼容IE8+的CORS封装:
1 // 兼容IE8+ 只能发送get类型的异步跨域请求 2 function fnGetCorsRequest(url, data, fnSuccess, fnError) { 3 var xhr = new XMLHttpRequest; 4 if (‘withCredentials‘ in xhr) { 5 xhr.open(‘get‘, url + ‘?‘ + fnGetURLParam(data), true); 6 } else { 7 xhr = new XDomainRequest; 8 xhr.open(‘get‘, url + ‘?‘ + fnGetURLParam(data)); 9 } 10 xhr.send(null); 11 if (fnSuccess) { // 成功 12 xhr.onload = function () { 13 fnSuccess(xhr.responseText); 14 } 15 } 16 if (fnError) { // 失败 17 xhr.onerror = function (e) { 18 fnError(e); 19 } 20 } 21 return xhr; 22 } 23 // 测试 24 var xhr = fnGetCorsRequest( 25 ‘http://localhost/ajax/data.php‘, 26 {name: ‘hum‘, age: 20}, 27 function (data) { 28 console.log(data); 29 }, 30 function (e) { 31 console.log(e); 32 } 33 ); 34 35 // 获取URLParam的辅助方法 36 function fnGetURLParam(data) { 37 var urlParam = []; 38 for (var key in data) { 39 urlParam.push(encodeURIComponent(key) + ‘=‘ + encodeURIComponent(data[key])); 40 } 41 return urlParam.join(‘&‘); 42 }
IE11+和标准浏览器的CORS跨域封装:
1 // 兼容IE11+和标准浏览器 支持异步和同步 get和post 2 function fnGetCorsRequest(method, url, data, bAsyn, fnSuccess, fnError) { 3 var xhr = new XMLHttpRequest; 4 data = fnGetURLParam(data); 5 if (method == ‘get‘) { 6 url += ‘?‘ + data; 7 data = null; 8 } 9 xhr.open(method, url, bAsyn); 10 if(method == ‘post‘){ 11 xhr.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded‘); // setRequestHeader要放在open后 12 } 13 xhr.onload = function () { 14 fnSuccess && fnSuccess(xhr.responseText); 15 } 16 xhr.onerror = function (e) { 17 fnError && fnError(e); 18 } 19 xhr.send(data); // 支持同步 send方法应该放在事件绑定后面 20 21 return xhr; 22 } 23 // 测试 24 var xhr = fnGetCorsRequest( 25 ‘post‘, 26 ‘http://localhost/ajax/data.php‘, 27 {name: ‘hum‘, age: 20}, 28 true, 29 function (data) { 30 console.log(data); 31 }, 32 function (e) { 33 console.log(e); 34 } 35 ); 36 37 // 获取URLParam的辅助方法 38 function fnGetURLParam(data) { 39 var urlParam = []; 40 for (var key in data) { 41 urlParam.push(encodeURIComponent(key) + ‘=‘ + encodeURIComponent(data[key])); 42 } 43 return urlParam.join(‘&‘); 44 }
1 var oImg = new Image; 2 oImg.src = ‘http://blog.smdcn.net/dizxcv.png‘; 3 oImg.onload = function(){ 4 document.body.innerHTML += ‘<img src="‘ + oImg.src + ‘" />‘; 5 }
缺点:只能get请求,无法访问响应文本......
1 $data = json_encode(array( // php代码 2 ‘name‘ => $_GET[‘name‘], 3 ‘age‘ => $_GET[‘age‘] 4 )); 5 $callback = $_GET[‘callback‘]; 6 echo $callback.‘(‘. $data .‘)‘;
1 function fnUseJSONP(url, data, fnCallback) { // js代码 2 var oScript = document.createElement(‘script‘); 3 oScript.type = ‘text/javascript‘; 4 if (data) { 5 oScript.src = url + ‘?‘ + fnGetURLParam(data) + ‘&callback=!‘ + fnCallback;// 注意这个!号 6 } else { 7 oScript.src = url + ‘?callback=!‘ + fnCallback; // 注意这个!号 8 } 9 // 请求返回!function (data) { console.log(data); }({"name":"hum","age":"20"}) 10 // 为了让该函数自执行可以加上!等 11 document.body.appendChild(oScript); 12 } 13 14 fnUseJSONP( 15 ‘http://localhost/ajax/data.php‘, 16 {name: ‘hum‘, age: 20}, 17 function (data) { 18 console.log(data); 19 } 20 ); 21 22 // 获取URLParam的辅助方法 23 function fnGetURLParam(data) { 24 var urlParam = []; 25 for (var key in data) { 26 urlParam.push(encodeURIComponent(key) + ‘=‘ + encodeURIComponent(data[key])); 27 } 28 return urlParam.join(‘&‘); 29 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。