web api 跨域請求,ajax跨域調用webapi

原文:https://www.cnblogs.com/inconceivable/p/5504732.htmljavascript

一、跨域問題僅僅發生在Javascript發起AJAX調用,或者Silverlight發起服務調用時,其根本緣由是由於瀏覽器對於這兩種請求,所給予的權限是較低的,一般只容許調用本域中的資源,除非目標服務器明確地告知它容許跨域調用。假設咱們頁面或者應用已在 http://www.test1.com 上了,而咱們打算從 http://www.test2.com 請求提取數據。通常狀況下,若是咱們直接使用 AJAX 來請求將會失敗,瀏覽器也會返回「源不匹配」的錯誤,"跨域"也就以此由來。html

二、什麼是跨域呢?java

JavaScript出於安全方面的考慮,不容許跨域調用其餘頁面的對象。一般來講,跨域分爲如下幾類:
在跨域問題上,域僅僅是經過「URL的首部」來識別而不會去嘗試判斷相同的ip地址對應着兩個域或兩個域是否在同一個ip上。
 
三、當發起AJAX跨域(cross domain)調用ASP.NET MVC或者ASP.NET Web API編寫的服務時,會發生沒法訪問的狀況。
出現以下錯誤信息
在這裏跟你們解釋一下 Access-Control-Allow-Origin是HTML5中定義的一種服務器端返回Response header,用來解決資源(好比字體)的跨域權限問題。
當Access-Control-Allow-Origin後面跟URL 或 *,若是是 URL 則只會容許來自該 URL 的請求,* 則容許任何域的請求
例如:header('Access-Control-Allow-Origin:http://A.abc.com')||header('Access-Control-Allow-Origin:*')
意思是說只有當你請求的資源被容許跨域的時候才能夠被訪問。
那麼咱們該怎麼設置Access-Control-Allow-Origin呢?
 
四、第一種是用JSONP來得到跨域的數據,而WebAPI自己是不支持javascript的callback的
  比較一下json與jsonp格式的區別:
json格式:
{
    "message":"獲取成功",
    "state":"1",
    "result":{"name":"工做組1","id":1,"description":"11"}
}
jsonp格式:
callback({
    "message":"獲取成功",
    "state":"1",
    "result":{"name":"工做組1","id":1,"description":"11"}
})

看出來區別了吧,在url中callback傳到後臺的參數是神馬callback就是神馬,jsonp比json外面有多了一層,callback()。jquery

只須要給全局註冊一個JsonCallbackAttribute,就能夠判斷接口的訪問是屬於跨域,仍是非跨域,正常的返回。git

由於咱們的接口,多是用來給 移動端(Android 、IOS)作數據接口,也有多是給網站用,因此,考慮到可能存在跨域的問題。github

   GlobalConfiguration.Configuration.Filters.Add(new JsonCallbackAttribute());
複製代碼
複製代碼
 public class JsonCallbackAttribute : ActionFilterAttribute
    {
        private const string CallbackQueryParameter = "callback";

        public override void OnActionExecuted(HttpActionExecutedContext context)
        {
            var callback = string.Empty;

            if (IsJsonp(out callback))
            {
                var jsonBuilder = new StringBuilder(callback);

                jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result);

                context.Response.Content = new StringContent(jsonBuilder.ToString());
                //context.Response.Content = new StringContent("C(\"a\")");
            }

            base.OnActionExecuted(context);
        }

        private bool IsJsonp(out string callback)
        {
            callback = System.Web.HttpContext.Current.Request.QueryString[CallbackQueryParameter];

            return !string.IsNullOrEmpty(callback);
        }
複製代碼
複製代碼

結合下面圖片不難開出,請求的地址帶回了,callback的參數標識。web

固然也能夠用解決跨域問題的jQuery插件-jquery-jsonp,有第一種方式的基礎,使用jsonp插件也就比較簡單了,server端代碼無需任何改動。json

五、服務端直接修改配置文件,我的認爲這種方式好一點,畢竟咱們所寫的api是對外公開的,安全訪問的控制仍是要經過其餘方法來保證。api

針對ASP.NET MVC,只須要在web.config中添加以下的內容便可跨域

<system.webServer>

<httpProtocol>

<customHeaders>

<add name="Access-Control-Allow-Origin" value="*" />

<add name="Access-Control-Allow-Headers" value="Content-Type" />

<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />

</customHeaders>

</httpProtocol>

<handlers>

<remove name="ExtensionlessUrlHandler-Integrated-4.0" />

<remove name="OPTIONSVerbHandler" />

<remove name="TRACEVerbHandler" />

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

</handlers>

</system.webServer>

  

針對ASP.NET Web API,除了上面這樣的設置,還須要添加一個特殊的設計,就是爲每一個APIController添加一個OPTIONS的方法,但無需返回任何東西。

public string Options()

{

return null; // HTTP 200 response with empty body

}

六、還有用CORS(跨域資源共享,Cross-Origin Resource Sharing)來解決的, CORS定義一種跨域訪問的機制,可讓AJAX實現跨域訪問。CORS 容許一個域上的網絡應用向另外一個域提交跨域 AJAX 請求。實現此功能很是簡單,只需由服務器發送一個響應標頭便可。

hander() 設置, 「*」號表示容許任何域向咱們的服務端提交請求
     

  也能夠設置指定的域名,如域名 http://www.test2.com ,那麼就容許來自這個域名的請求

     
這種沒有仔細研究,其實跟上面的配置文件,差很少,都是去設置響應頭。
 
本文是結合好多其餘做者的文章:
http://www.cnblogs.com/chenxizhang/p/3821703.html
http://www.cnblogs.com/sunxucool/p/3433992.html
http://www.cnblogs.com/Darren_code/p/cors.html
相關文章
相關標籤/搜索