前後端分離的一些問題

2021-09-24 22:47:49 字數 4367 閱讀 7200

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訪問

header(『access-control-allow-credentials: true』);

在後端程式載入前執行以下函式,避免options請求浪費系統資源和資料庫資源。

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已經配置了前端目錄和主頁頁面訪問,是不能再加上...