restful架構是目前比較流行的一種網際網路軟體架構,在此架構之下的瀏覽器前端和手機端能共用後端介面。
但是涉及到js跨域呼叫介面總是很頭疼,下邊就跟著chrome的報錯資訊一起來解決一下。
假設:前端網域名稱為front.ls-la.me,後端網域名稱為api.ls-la.com。前端需要訪問的介面為需要用get方式訪問。
現在,用ajax向後端傳送請求,得到第乙個錯誤。(cors跨域的寫法參考:
提示響應頭沒有access-control-allow-origin這一項,谷歌得知需要在伺服器指定哪些網域名稱可以訪問後端介面,設定之:
header(『access-control-allow-origin:再次傳送請求,又報錯。// 如果你不怕扣工資可以這麼設:header(『access-control-allow-origin: *』);
意思是ajax頭資訊中有x-requested-with這一字段,後端不允許。那就讓允許吧:
header(『access-control-allow-headers: x-requested-with』);好了,這下不報錯了,但是仔細分析請求過程,發現瀏覽器向介面位址傳送了兩個請求,第乙個是options方式,第二個才是get方式。
這裡的第乙個請求叫做「preflight table request(預檢表請求,微軟這麼翻譯的,不知道對不對)」。這個請求是在跨域的時候瀏覽器自行發起的,作用就是先請求一下看看伺服器支不支援當前的訪問。如果不支援,就會報之前所列的錯誤;如果支援,再傳送正常的get請求,返回相應的資料。
但是每個請求之前都要這麼options一下,作為典型**座表示非常不能忍。需要告訴瀏覽器你搞一下是個意思,老這麼搞就沒意思了:
// 告訴瀏覽器我支援這些方法(後端不支援的方法可以從這裡移除,當然你也可以在後邊加上options方法。。。)好了,事情至此告一段落。header(『access-control-allow-methods: get, put, post, delete』);
// 告訴瀏覽器我已經記得你了,一天之內不要再傳送options請求了
header('access-control-max-age: 』 . 3600 * 24);
才怪!突然有一天測試妹子跑來跟你說**記不住使用者的狀態,一檢查發現跨域的時候cookie失效了。
js在傳送跨域請求的時候請求頭里預設是不帶cookie的,需要讓他帶上:
);// angular 三選一
總之就是要在xhr裡設定一下withcredentials = true,然後跨域請求就能帶上cookie了。注意這裡的cookie遵循同源策略,也就是後端傳送的cookie也是屬於網域名稱api.ls-la.com的。
傳送乙個帶cookie的post請求,依舊報錯:
跟上邊那個x-requested-with報錯一樣,頭資訊不允許,後端改下:
header(『access-control-allow-headers: x-requested-with, content-type』);再來,還是報錯:
提示很明顯,後端**加一行,允許攜帶cookie訪問:
// 允許前端帶cookie訪問在後端程式載入前執行以下函式,避免options請求浪費系統資源和資料庫資源。header(『access-control-allow-credentials: true』);
function cors_options()
因為cors的出現,大大降低了跨域的難度,另到ajax有了更大的發揮空間,也導致了前後端更加容易實現。但是今天在實現前後端的時候發現了乙個問題。在進行session會話管理的時候,前端無法傳送cookie到後端,前端每次訪問後端都相當於一次新的會話,這樣就導致登入後的資訊是無法儲存的。客戶端每一次訪問都需要重新登入。
對於前端來說,seesion欄位是存在cookie中的。在跨域過程中,cookie是預設不傳送的。就算後端返回set-cookie欄位,前端也不會儲存cookie,更不會在下一次訪問的時候傳送到後端了。
因此只要前端可以把cookie傳送到後端,後端就可以根據cookie拿到seeion欄位進行會話驗證。
進過重新對cors的學習,只要通過3步,就可以讓會話保持。
第一步在ajax中設定,withcredentials: true。
例如:
$.
ajax(}
);
預設情況下,跨源請求不提供憑據(cookie、http認證及客戶端ssl證明等)。通過將withcredentials屬性設定為true,可以指定某個請求應該傳送憑據。
服務端的access-control-allow-origin 不可以設定為"*",必須指定明確的、與請求網頁一致的網域名稱
服務端的 access-control-allow-credentials: true,代表伺服器接受cookie和http認證資訊。因為在cors下,是預設不接受的。
ps:在spring boot 中,可以寫乙個配置類來實現
@configuration
public
class
corsconfiguration};
}}
在ssm中可以寫乙個filter實現。
public
class
ajaxfilter
extends
onceperrequestfilter
}
web.xml
ajaxfilter<
/filter-name>
class
>***x.ajaxfilter<
/filter-
class
>
<
!-- 自定義過濾器 --
>
<
/filter>
ajaxfilter<
/filter-name>
/*
前後端分離的一些想法
本文主題應該是前後端分離,我上面的建議是個徹底方案,要革以前系統的命,對存量系統那該如何處理,答案還是重構 想方設法逐步減少已經發現的前後端耦合度高的問題,這個跟我之前的建議就是小重構和大重構的區別,如果有人覺得我上面建議合適,前端組應該馬上提供一套這樣的框架出來,這樣後面的新系統就不會在迴圈前面的...
nginx前後端分離遇到的一些坑
公司最近在重構專案,使用nginx做前端伺服器,負載均衡,限速等等,遇到了一些坑,記錄下來.前端頁面伺服器 server 讓nginx攔截80埠,然後直接去nginx根目錄下的html wanmor cloud platform frontend wanmor cloud platform fron...
前後端分離的一些注意事項
nginx配置反向 可以解決前後端分離帶來的跨域問題。nginx配置location的時候,如果配置了乙個新的server,是 根目錄訪問主頁,那麼再根據資源路徑訪問後台伺服器時,需要配置proxy pass伺服器 這個時候,因為根目錄的location已經配置了前端目錄和主頁頁面訪問,是不能再加上...