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

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

跨域訪問

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

  以下,域名相同的狀況下,3000端口的應用沒法直接訪問8080端口的服務。html

  

跨域資源共享CORS

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

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

  

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

  若是Origin指定的域名在許可範圍內,服務器返回的響應,會多出幾個頭信息字段,以下:json

  

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

  • 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"); 

  至此,先後端分離項目便可完成跨域訪問與會話保持!

 

參考連接

相關文章
相關標籤/搜索