導語
之前寫過一篇文章Ajax跨域請求COOKIE無法帶上的解決辦法,這兩天正好好好的查了一下相關知識,做來總結一下
一、傳統
ajax跨域訪問是一個老問題了,解決方法很多,比較常用的是JSONP方法,JSONP方法是一種非官方方法,而且這種方法只支持GET方式,不如POST方式安全。
即使使用jQuery的jsonp方法,type設為POST,也會自動變為GET。
官方問題說明:
"script": Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string parameter, "_=[TIMESTAMP]", to the URL unless the cache option is set to true.Note: This will turn POSTs into GETs for remote-domain requests.
如果跨域使用POST方式,可以使用創建一個隱藏的iframe來實現,與ajax上傳圖片原理一樣,但這樣會比較麻煩。
二、當跨域訪問時,瀏覽器會發請求嗎
沒有設置跨越,瀏覽器會返回
XMLHttpRequest cannot load http://google.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.jsbin.io' is therefore not allowed access.
在開發工具中Network並沒有任何記錄。但實際請求仍會被發送,只是在瀏覽器做了攔截。
參考:Access-Control-Allow-Origin與跨域
三、Access-Control-Allow-Origin來實現跨域訪問
隨着跨域請求的應用越來越多,W3C提供了跨域請求的標准方案(Cross-Origin Resource Sharing)。IE8、Firefox 3.5 及其以后的版本、Chrome瀏覽器、Safari 4 等已經實現了 Cross-Origin Resource Sharing 規范,實現了跨域請求。所有和CORS相關的response header都是以“Access-Control-“為前綴的:
- Access-Control-Allow-Origin(必須) 這個必須包含在所有合法的跨域請求的response中,其值要么是Origin header中的值,要么就是”*“允許任何域的請求。
- Access-Control-Allow-Credentials(可選),默認情況下cookie是不包含在CORS請求中的,使用這個header將會指明要在CORS請求中包含cookie,它的有效值是true, 如果不需要cookie, 正確的做法不是將其值設為false, 而是根本就不要這個包含header.
- Access-Control-Expose-Header(可選),XMLHttpRequest 2 object中有一個getResponseHeader()方法,用以返回特定的response header,但是它只能得到簡單的響應header,如果想讓客戶端訪問到其他的一些header, 必須設定這個 Access-Control-Expose-Header,它的值是以逗號分隔的你想暴漏給客戶端的header。
在服務器響應客戶端的時候,帶上Access-Control-Allow-Origin頭信息。
- 如果設置 Access-Control-Allow-Origin:*,則允許所有域名的腳本訪問該資源。
- Access-Control-Allow-Origin:http://www.phpddt.com.com,允許特定的域名訪問。
參考:
- 利用Access-Control-Allow-Origin響應頭解決跨域請求
- 跨源資源共享 Cross Origin Resource Sharing(CORS) (重點)
- ajax 設置Access-Control-Allow-Origin實現跨域訪問
四、Asp.Net封裝Access-Control-Allow-Origin頭信息
1.Web.config
在Web.config中加入統一的Access-Control-Allow-Origin返回頭信息,是最原始,也是最直接的。無論是在老版本WebForm還是Mvc都適用。
CORS on IIS7
For Microsoft IIS7, merge this into the web.config file at the root of your application or site:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
2.自定義Attribute,來增加頭信息
a)創建一個attribute
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
b)應用到Controller中的Action
[AllowCrossSiteJson]
public ActionResult YourMethod()
{
return Json("data");
}
參考:ASP.NET MVC 設置Access-Control-Allow-Origin
3.Microsoft.AspNet.Cors
使用Microsoft.AspNet.Cors包,這個是微軟封裝好的一個類庫,原理和之前是一樣的,有興趣的話可以詳細參考如下的文章配置:
