關於WebAPI跨域踩到的一點坑


最近在嘗試前后端分離的WebAPI+AngularJS方案,在率先處理授權的時候,踩到了一點WebAPI跨域的坑,其實嚴格意義上來說也不算是坑吧,只是我自己對WebAPI不熟悉而已,這里我與大家分享一下。

先說一下我這邊遇到的情況:

我是在做登錄功能,使用的是微軟的OWin提供的組件來實現

對於WebAPI跨域,你如果去百度或者谷歌,基本上會有以下兩種答案:

一、在Web.config增加配置

在Web.config中system.webServer節點下面,增加配置項,設置輸出的http header,類似於如下代碼,主要是httpProtocol中的代碼:

<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>

在Web.config中增加相應配置之后,發現雖然header中會有相應的跨域需要的header,但是每次我請求token的post請求都會自動變成options請求最終導致400失敗,而且F12查看瀏覽器沒有報關於跨域失敗的錯誤。

 

二、使用Microsoft.AspNet.WebApi.Cors進行跨域

這是網上的第二種,也是最多的一種方案,引用這個類庫,然后在WebApiConfig.cs中Register方法中進行注冊,大概代碼如下:

var cors = new EnableCorsAttribute("*", "*", "*");
GlobalConfiguration.Configuration.EnableCors(cors);

就這兩行,然后我把Web.config中的代碼拿掉,只加這個的時候,瀏覽器端response回來的根本就沒有了跨域的header,再次宣布失敗~

 

三、最終的解決方案

經過我多方找資料,發現好像根本不是WebAPI的跨域問題,而是OWin他本身有跨域問題需要解決,即使你Web.API支持了跨域,那Owin也不認(OWin好屌,一個組件竟然不認全局配置)。那找到了原因方法就好找了,我找到了微軟還有一個類庫,叫Microsoft.Owin.Cors,引用之后,在Startup中的Configuration方法里面啟用授權的時候,調用一下 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);方法。

加上之后,我直接使用angularJS向后端POST一個Json對象,類似於如下:

var loginData = {
            username: 'admin',
            password: '',
            client_id: systemSetting.clientId,
            client_secret: systemSetting.clientSecret,
            grant_type: 'code'
        };

發現請求成功了,但是授權卻失敗了,他告訴我說grant_type不受支持,但是我確定我的這個參數傳遞的沒有任何問題,經過一番查閱資料,發現需要把這個改成類似於URL傳遞參數的形式(原因未查明):

var requestData="grant_type=password&username=" + loginData.username + "&password=" + loginData.password;

經過如上一番折騰,終於可以在客戶端正確獲取token.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM