vue前後端分離使用fetch 跨域請求時 session失效問題解決
前臺是vue使用fetch請求後臺的登入方法,但是前臺瀏覽器的控制檯中的sessionid沒有,要麼就是跟後臺的sessionid不一致,導致後臺取驗證碼的時候是null,因為驗證碼是後臺存在session中
在用fetch進行網路請求的時候,發現每次請求到服務端的時候,他的sessionId 都是不一樣的,後面排查原來是在請求的時候fetch預設是不會帶上本地jsessionId,以至於服務端無法接收到,所以會重新建立一個新的session。
針對這個問題,完整寫法是:主要是credentials: 'include' 是解決跨域session丟失的問題,加上這一行以後,前端瀏覽器中的sessionid和後臺列印的sessionid是一致的,但是引數傳不過來,最後加了一個method:'post',就可以了
let fd=new FormData();
fd.append('username',this.userName);
fd.append('password',this.userPwd);
fd.append('checkCode',this.code);
fetch(`${apiUrl}/login`,{
method:'post',
body:fd,
credentials: 'include'
}).then((res)=>res.json()).
then((res)=>{
console.log(res);
}).catch((res)=>console.log(res));
後臺程式碼
(注:
response.setHeader("Access-Control-Allow-Origin", "http://192.168.1.136:8080";);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Allow-Credentials", "true");//是否支援cookie跨域
後臺什麼都不需要加,根本不需要加跨域這些東西)。
javascript 使用fetch進行跨域請求時預設是不帶cookie的,所以會造成 session失效。
fetch(url, {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify({
data: options.data
})
})credentials: 'include' 可以是fetch 帶上cookie。但是問題了來。
原來在伺服器端設定header (php 伺服器)
header("Access-Control-Allow-Origin: *");
會報錯:
A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:8000' is therefore not allowed access.
可以看到不允許 使用‘*’ 號了,那麼就改成 訪問域名(這裡是本地呼叫所以是 http://localhost:8000)
header("Access-Control-Allow-Origin: http://localhost:8000");
改完後再次傳送請求,還是報錯
Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials. Origin 'http://localhost:8000' is therefore not allowed access.
說'Access-Control-Allow-Credentials 頭必須是true,那麼繼續增加
header("Access-Control-Allow-Credentials: true");
增加完後可以正常訪問了,而且session也有了。
ps: fetch 有個mode 是no-cors ,發現設定後返回的status是0,查資料後
no-cors
mode
is only to CDN content, such as scripts, CSS and image, you cannot be used for getting data,response.status
= 0
is right behavior
no-cors 模式只能用來獲取CDN內容,比如指令碼,css檔案和圖片,如果用來獲取資料比如json格式就會返回status=0
針對於解決前後臺sessionid一致問題以後又遇到 引數傳遞不到後臺,最後這樣解決:
終極方案(推薦使用):
既然fetch不會自動轉FormData,那我們自己new一個FormData,直接傳給body。
在FormData中也可以傳遞位元組流實現上傳圖片的功能。參考:http://blog.csdn.net/codetomylaw/article/details/52446786
[javascript] view plain copy
-
let formData = new FormData();
-
formData.append("name","admin");
-
formData.append("password","admin123");
-
etch(url , {
-
method: 'POST',
-
headers: {},
-
body: formData,
-
).then((response) => {
-
if (response.ok) {
-
return response.json();
-
}
-
).then((json) => {
-
alert(JSON.stringify(json));
-
).catch((error) => {
-
console.error(error);
-
);
這樣我們就可以在Server端獲取到name和password的值了。