1. 程式人生 > 實用技巧 >Ajax請求攜帶Cookie

Ajax請求攜帶Cookie

目錄

xhr

先來了解下xhr
xhr,全稱為XMLHttpRequest,用於與伺服器互動資料,是ajax功能實現所依賴的物件,jquery中的ajax就是對 xhr的封裝。
還有axios和fetch請求都屬於xhr請求,都是基於標準 Promise 實現。

ajax cookie跨域處理

簡單說說cookiesession的關係

不少朋友搞的不是特別清楚,一知半解的,在這裡闡述下

cookie儲存於客戶端瀏覽器,預設生命週期跟隨瀏覽器,瀏覽器關閉,cookie就會失效,tab標籤也關閉了並不會失效

session儲存於伺服器,比如tomcat,預設失效時間30分鐘,當然也可以通過redis來儲存。

這裡登入做個示例說明

未登入狀態下,匿名使用者通過客戶端瀏覽器請求資料,都是無狀態的(服務端不知道你是誰

使用者進行請求登入操作,登入成功,服務端會在response header里加一個Set-Cookie寫入瀏覽器中。

之後客戶端在以後的請求中,會自動在請求頭中攜帶此cookie。

cookie有一些屬性,比如

  • 失效時間(跟隨瀏覽器,但是也可以進行持久化。跟localstorage和sessionstorage類似)

  • httponly(設定為true的話,客戶端在控制檯就獲取不到)

  • path(預設為/)

同源情況下,比如是前後端不分離的專案,xhr(ajax)請求沒有任何問題,但是會發現,不支援cookie跨域

非同源情況下,xhr(ajax)請求服務端處理了,但是不會進行響應,會顯示如下錯誤。也就是出現了跨域問題。

所以,解決介面跨域和解決xhr cookie跨域,是不一樣的。

解決cookie跨域需要客戶端和服務端都做處理,主要操作在服務端。

客戶端

ajax請求新增該引數即可

xhrFields: {
    withCredentials: true
},

同理axios也是如此

axios.defaults.withCredentials = true

注意,修改cookie值直接document修改即可,請求的時候瀏覽器會自動攜帶的。
不需要在header中新增cookie頭,這樣做是沒有任何意義的。比如

headers: {
    'Cookie': 'JSESSIONID=6FA9E27092EC212E439851D4831AADE6'
}

服務端

新增允許跨域操作,此處表示Spring框架,直接用@CrossOrigin處理即可(最為簡單)

@CrossOrigin(value = "*", allowCredentials = "true")

服務端設定跨域的幾種方式

方式一 重寫addCorsMappings方法

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
            .maxAge(3600)
            .allowCredentials(true);
    }
}

方式二 對單個介面處理

// 需要設定前端請求的url。不支援*
responses.setHeader("Access-Control-Allow-Origin", "http://localhost:63342");
// 設定允許跨域的方法
responses.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
// 之後需要設定允許cookie跨域
response.setHeader("Access-Control-Allow-Credentials", "true");

方式三 @CrossOrigin註解

@CrossOrigin(value = "*", allowCredentials = "true")

方式四 nginx配置新增允許跨域請求

server {
    listen 5566;
    server_name localhost;
        # 指定客戶端的請求地址
        add_header 'Access-Control-Allow-Origin' 'http://localhost:63342';
        add_header 'Access-Control-Allow-Credentials' true;
        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization,token,r,sign,time";

    location /  {

      if ($request_method = OPTIONS ) {
                   return 200;
         }

           proxy_method get;

           proxy_set_header X-real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

           proxy_pass  http://127.0.0.1:5005;
           proxy_set_header Host $host;
       }

}

OK,完美解決!