我們知道ajax不能跨域訪問,但是有時我們確實需要跨域訪問獲取數據,所以JSONP就此誕生了,其本質使用的是Script標簽,除JSONP以外還有另外實現跨域方式
一、手動實現JSONP跨域
1、首先創建一個Web項目,在這里我使用一般處理程序
1 public class Demo : IHttpHandler 2 { 3 public void ProcessRequest(HttpContext context) 4 { 5 //接收參數 6 string callBack = context.Request["callBack"]; 7 string uName = context.Request["uName"]; 8 string data = "({\"name\":\"" + uName + "\",\"age\":\"23\"})"; 9 string josnStr = callBack + data; 10 context.Response.Write(josnStr); 11 } 12 13 public bool IsReusable 14 { 15 get 16 { 17 return false; 18 } 19 } 20 }
2、創建一個新Web項目並新建html文件
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>手動實現JSONP實現跨域請求Demo</title> 6 <!--引用jquery--> 7 <script src="/jquery-1.7.1.js"></script> 8 <script type="text/javascript"> 9 var urlPrefix = "http://localhost:2571"; 10 //js跨域請求中的回調函數 11 function fun(data) { 12 for (var i in data) { 13 alert(data[i]); 14 } 15 } 16 //js跨域請求 17 function jsRequest() { 18 var script = document.createElement("script"); 19 script.setAttribute("id", "script1"); 20 script.setAttribute("type", "text/javascript"); 21 script.setAttribute("src", urlPrefix + "/demo.ashx?uName=zzq&callBack=fun"); 22 //添加到body之后 23 document.documentElement.appendChild(script); 24 //使用完后移除 25 $("#script1").remove(); 26 } 27 28 //jq跨域請求 29 function jqRequest() { 30 $.ajax( 31 { 32 url: urlPrefix + "/demo.ashx", 33 type: "get", 34 data: { uName: "zzq" }, 35 dataType: "jsonp", //指定Jq發送jsonp請求 36 jsonpCallback: "fun", //指定回調函數,沒有此項可以直接在success中寫回調 37 jsonp: 'callBack' //默認callback 38 //success: function (data) { 39 // for (var i in data) { 40 // alert(data[i]); 41 // } 42 //} 43 }); 44 } 45 </script> 46 </head> 47 <body> 48 <!--Js跨域請求和Jquery跨域請求都不支持post方式,jquery跨域其實就是JS跨域的封裝--> 49 <input type="button" value="使用原生JS跨域請求" onclick="jsRequest()" /> 50 <input type="button" value="使用Jquery跨域請求" onclick="jqRequest()" /> 51 </body> 52 </html>
3、測試,將兩個網站都打開,http://localhost:2571:填寫第一步創建網站的地址
兩個請求都是返回同樣的信息
二、添加請求頭實現跨域
1、同樣是先創建一個Web項目,跟上面一樣使用的是一般處理程序,*.ashx,這里我只貼出重要的部分
1 public void ProcessRequest(HttpContext context) 2 { 3 //接收參數 4 string uName = context.Request["uName"]; 5 string data = "{\"name\":\"" + uName + "\",\"age\":\"23\"}"; 6 //只需在服務端添加以下兩句 7 context.Response.AddHeader("Access-Control-Allow-Origin", "*"); 8 //跨域可以請求的方式 9 context.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET"); 10 context.Response.Write(data); 11 }
2、創建一個新Web項目並新建html文件
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>添加請求頭跨域訪問Demo</title> 6 <script src="/jquery-1.7.1.js"></script> 7 <script type="text/javascript"> 8 function crosRequest() { 9 $.post("http://localhost:2571/XHR2Demo.ashx", { uName: "zzq" }, function (data) { 10 for (var i in data) { 11 alert(data[i]); 12 } 13 }, "json") 14 } 15 </script> 16 </head> 17 <body> 18 <input type="button" value="添加請求頭跨域訪問" onclick="crosRequest()" /> 19 </body> 20 </html>
3、最后就是測試,查看效果了
加了以下信息
也可以直接在web.config中進行配置(放到 system.webServer 節點下)
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*"/> <add name="Access-Control-Allow-Headers" value="*"/> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE"/> </customHeaders> </httpProtocol>
三、CROS實現WebApi跨域
1、新建WebApi項目並通過NuGet下載程序包,搜索程序包【Microsoft.AspNet.WebApi.Cors】,一般我喜歡下載一個中文包,方便查看注釋
2、在Global的Application_Start中加上如下代碼
1 var cors = new EnableCorsAttribute("*", "*", "*"); 2 GlobalConfiguration.Configuration.EnableCors(cors);
注意這兩句放Application_Start方法最前面,否則會導致不能跨域,暫不知其原因
3、創建一個新Web項目並新建html文件
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>WebApi跨域Demo</title> 6 <script src="/jquery-1.10.2.js"></script> 7 <script type="text/javascript"> 8 $(function () { 9 getData(); 10 }); 11 function getData() { 12 var furl = "http://localhost:19125/api/home"; 13 $.get(furl, function (data) { 14 for (var i = 0; i < data.length; i++) { 15 alert(data[i]); 16 } 17 }); 18 } 19 </script> 20 </head> 21 <body> 22 WebApi跨域Demo 23 </body> 24 </html>
4、最后測試看看效果
加了以下信息
總結
1、手動創建JSONP跨域
優點:無瀏覽器要求,可以在任何瀏覽器中使用此方式
缺點:只支持get請求方式,請求的后端出錯不會有提示,造成不能處理異常
2、添加請求頭實現跨域
優點:支持任意請求方式,並且后端出錯會像非跨域那樣有報錯,可以對異常進行處理
缺點:兼容性不是很好,IE的話 <IE10 都不支持此方式
第三種的話我覺得原理就是第二種的實現,實際測試發現跟第二種一樣,通過查看請求報文中的Head也能看出