React:快速上手(8)——前后端分離的跨域訪問與會話保持


React:快速上手(8)——前后端分離的跨域訪問與會話保持

跨域訪問

  跨域是指從一個域名的網頁去請求另一個域名的資源。比如從http://www.baidu.com/ 頁面去請求 的資源。跨域的嚴格一點的定義是:只要 協議,域名,端口有任何一個的不同,就被當作是跨域。 

  如下,域名相同的情況下,3000端口的應用無法直接訪問8080端口的服務。

  

跨域資源共享CORS

  它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。CORS需要瀏覽器與服務器的雙向支持。整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信

  在簡單的跨域Ajax請求中,會在頭部信息中添加Origin參數用於表面這個請求來自哪里,如下

  

  如果Origin指定的源,不在許可范圍內,服務器會返回一個正常的HTTP回應。瀏覽器發現,這個回應的頭信息沒有包含Access-Control-Allow-Origin字段(詳見下文),就知道出錯了,從而拋出一個錯誤,被XMLHttpRequestonerror回調函數捕獲。注意,這種錯誤無法通過狀態碼識別,因為HTTP回應的狀態碼有可能是200。

  如果Origin指定的域名在許可范圍內,服務器返回的響應,會多出幾個頭信息字段,如下:

  

  其中,幾個重要的頭信息如下:

  • Access-Control-Allow-Origin:該字段是必須的。它的值要么是請求時Origin字段的值,要么是一個*,表示接受任意域名的請求。
  • Access-Control-Allow-Credentials:該字段可選。它的值是一個布爾值,表示是否允許發送Cookie。默認情況下,Cookie不包括在CORS請求之中。設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可。

服務器端的處理

  如上所述,CORS請求的關鍵是在后端,即將Origin添加到服務器的許可范圍內。在SpringBoot應用中,我們可以編寫一個攔截器,來實現:

@Component
public class CorsInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, If-Modified-Since");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

  這里直接允許了所有源,在實際開發中,必須指定可信范圍的源。

客戶端處理

  對於使用creat-react-app構建的項目,可以直接在package.json下配置,具體如下  

{
  "name": "recommender",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://代理地址",
  "dependencies": {
    "antd": "^3.23.3",
   ...  
  },
}

 

 

會話保持

  CORS請求默認不發送Cookie和HTTP認證信息。如果要把Cookie發到服務器,一方面要服務器同意,指定Access-Control-Allow-Credentials為true。另一方面,開發者必須在AJAX請求中打開withCredentials屬性

  在Axios中,可以簡單設置如下:

import axios from 'axios'
//方法1
axios.defaults.withCredentials =true;

//方法2
let config = {headers: {'Content-Type': 'multipart-/form-data'},withCredentials: true};

axios.post("http://127.0.0.1:8080/get.do", null, config).then((response) => {alert(response.data)})
   

  服務端的處理,我們已經在上述代碼中實現了,即

response.addHeader("Access-Control-Allow-Credentials", "true");

  至此,前后端分離項目即可完成跨域訪問與會話保持!

 

參考鏈接


免責聲明!

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



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