ajax跨域請求問題及解決辦法總結


1.瀏覽器的同源策略及規避方法

  目前,所有瀏覽器都實行同源政策。即協議、域名、端口都相同的URI稱為"同源"。不同源的url之間:

          a.無法讀取cookie、localstorage、indexDB

          b.無法獲取DOM

          c.無法發送ajax請求

      

       document.domain規避半同源網頁間不能共享cookie:

    cookie是服務器寫入瀏覽器的一段信息。同源網頁之間才能共享cookie。

    一級域名相同,二級域名不同的網頁之間允許通過設置document.domain='一級域名'的方式共享cookie。另外服務器在設置cookie的時候,指定cookie所屬的域名為一級域     名,這樣的話不需要做任何操作.

 

  postMesage規避不同源網頁之間不能共享數據:

    html5新增的跨文檔通信API為window對象新增了一個方法window.postMesage允許跨窗口通信,無論這兩個窗口是否同源。

              postMessage方法有兩個參數,第一個為需要傳遞的數據,第二個為傳送目標窗口地址。通過window.addEventListener('message',function(){})監聽window的message事件    獲取數據。message事件的event對象有三個屬性:event.source =>發送消息的窗口  event.origin=>消息發向的網址  event.data=>消息內容。

 

       window.name規避父子窗口之間不能共享數據:(父窗口打開iframe子窗口)

    瀏覽器窗口有window.name屬性。這個屬性的最大特點是,無論是否同源,只要在同一個窗口里,前一個網頁設置了這個屬性,后一個網頁可以讀取它。

    這種方法的優點是,window.name容量很大,可以放置非常長的字符串;缺點是必須監聽子窗口window.name屬性的變化,影響網頁性能。         

  

2.ajax請求跨域

  同源政策規定,AJAX請求只能發給同源的網址,否則就報錯。

       除了架設服務器代理(瀏覽器請求同源服務器,再由后者請求外部服務),有三種方法規避這個限制:

    a.jsonp (利用script標簽不受同源策略影響,只支持get方式,一般用jquery的jsonp封裝,接口需在返回值的外面包回調函數)

    b.websocket(一種通信協議,不受同源策略影響)

    c.cors(CORS是跨源資源分享(Cross-Origin Resource Sharing)的縮寫。是跨源AJAX請求的根本解決方法。)

  

 CORS需要瀏覽器和服務器同時支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低於IE10。
 整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。
 瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。
  因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。

常見后端解決方案:

  PHP后台配置

  PHP后台得配置幾乎是所有后台中最為簡單的,遵循如下步驟即可:

  • 第一步:配置Php 后台允許跨域

  <?php header('Access-Control-Allow-Origin: *');

header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');

//主要為跨域CORS配置的兩大基本信息,Origin和headers

  • 第二步:配置Apache web服務器跨域(httpd.conf中)

  原始代碼

<Directory />

    AllowOverride none

    Require all denied

</Directory>

  改為以下代碼

<Directory />

    Options FollowSymLinks

    AllowOverride none

    Order deny,allow

    Allow from all

</Directory>



  JAVA后台配置

  JAVA后台配置只需要遵循如下步驟即可:

  • 第一步:獲取依賴jar包下載 cors-filter-1.7.jar, java-property-utils-1.9.jar 這兩個庫文件放到lib目錄下。(放到對應項目的webcontent/WEB-INF/lib/下)

  • 第二步:如果項目用了Maven構建的,請添加如下依賴到pom.xml中:(非maven請忽視)

<dependency>

    <groupId>com.thetransactioncompany</groupId>

    <artifactId>cors-filter</artifactId>

    <version>[ version ]</version>

</dependency>

  其中版本應該是最新的穩定版本,CORS過濾器

  • 第三步:添加CORS配置到項目的Web.xml中(  App/WEB-INF/web.xml)

<!-- 跨域配置-->    

<filter>

        <!-- The CORS filter with parameters -->

        <filter-name>CORS</filter-name>

        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>        

        <!-- Note: All parameters are options, if omitted the CORS

             Filter will fall back to the respective default values.

          -->

        <init-param>

            <param-name>cors.allowGenericHttpRequests</param-name>

            <param-value>true</param-value>

        </init-param>  

        <init-param>

            <param-name>cors.allowOrigin</param-name>

            <param-value>*</param-value>

        </init-param>

        <init-param>

            <param-name>cors.allowSubdomains</param-name>

            <param-value>false</param-value>

        </init-param>

        <init-param>

            <param-name>cors.supportedMethods</param-name>

            <param-value>GET, HEAD, POST, OPTIONS</param-value>

        </init-param>       

        <init-param>

            <param-name>cors.supportedHeaders</param-name>

            <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>

        </init-param>

        <init-param>

            <param-name>cors.exposedHeaders</param-name>

            <!--這里可以添加一些自己的暴露Headers   -->

            <param-value>X-Test-1, X-Test-2</param-value>

        </init-param>

        <init-param>

            <param-name>cors.supportsCredentials</param-name>

            <param-value>true</param-value>

        </init-param>

        <init-param>

            <param-name>cors.maxAge</param-name>

            <param-value>3600</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <!-- CORS Filter mapping -->

        <filter-name>CORS</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

  請注意,以上配置文件請放到web.xml的前面,作為第一個filter存在(可以有多個filter的)

  • 第四步:可能的安全模塊配置錯誤(注意,某些框架中-譬如公司私人框架,有安全模塊的,有時候這些安全模塊配置會影響跨域配置,這時候可以先嘗試關閉它們)

 

  Node.js后台配置(express框架)

  Node.js的后台也相對來說比較簡單就可以進行配置。只需用express如下配置:

app.all('*', function(req, res, next) {

    res.header("Access-Control-Allow-Origin", "*");

    res.header("Access-Control-Allow-Headers", "X-Requested-With");

    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");

    res.header("X-Powered-By", ' 3.2.1')

        //這段僅僅為了方便返回json而已

    res.header("Content-Type", "application/json;");

    if(req.method == 'OPTIONS') {

        //讓options請求快速返回

        res.sendStatus(200);

    } else {

        next();

    }

});




免責聲明!

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



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