關於ajax跨域訪問導致session失效,cookie無法在本地儲存問題分析
阿新 • • 發佈:2019-01-22
大家可能遇到過,做登入時需要使用session來維護使用者與伺服器之前的關係,可能好多小夥伴不是很清楚session維護的原理,我簡單講一下session的原理,tomcat中session和cookie有著很密切的關聯如下圖
簡單理解就是客戶端和伺服器之間傳遞著一個sessionID,來維護使用者的會話狀態,伺服器端session生命週期為30min,客戶端cookie生命週期也為30min,但是當瀏覽器關閉時客戶端cookie也會隨之消失,伺服器端session不會消失,只能等待30分鐘之後,或者呼叫session.invalidate();可以銷燬session。(另外提醒可以使用firefox的firebug可以檢視網路cookie)
上述情況是同域時的情況,那麼下面就是關於跨域請求的問題了,首先理解一下什麼情況下是跨域,跨域、跨協議和跨埠都是跨域,我之前沒注意到跨埠也是跨域。那麼回到ajax這個問題上,ajax跨域有方式包括JSONP和CORS(跨域資源共享),我們知道ajax實現的核心是XMLHttpRequest介面,在XHR1中是不支援跨域(同域限制)的,但是XHR2中增加了對CORS的支援,使其能夠支援跨域,不過CORS預設是不攜帶cookie的。CORS是一種需要伺服器和前端配合的跨域技術,首先伺服器必須允許跨域請求,另外客戶端也需要新增響應的欄位才可以攜帶cookie。我是用的是jquery的的ajax,我們看看前端配置
$.ajax({
type:"POST",
url:url,
data:{data,data},
dataType:"json",
xhrFields: {withCredentials: true}, //與伺服器配合使用標識允許攜帶cookie
success:function(data){
},
error:function(XMLHttpRequest){
},
});
伺服器端我添加了CORSFilter.java
package com.chenhai.educationsystem.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CrossFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response=(HttpServletResponse) res; HttpServletRequest request = (HttpServletRequest)req; response.setHeader("Access-Control-Allow-Credentials", "true"); //支援跨域訪問,跨域訪問中cookie是預設忽略的,需要配合前端xhr的Credentials屬性使用,該屬性為true標識允許攜帶cookie //response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); //控制那些源可以訪問如:a.com response.setHeader("Access-Control-Allow-Headers", "content-type,authorization,x-requested-with"); //響應首部 Access-Control-Allow-Headers 用於 preflight request (預檢請求)中,列出了將會在正式請求的 Access-Control-Expose-Headers 欄位中出現的首部資訊。 response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); //響應首部 Access-Control-Allow-Methods 在對 preflight request.(預檢請求)的應答中明確了客戶端所要訪問的資源允許使用的方法或方法列表。 filterChain.doFilter(req, res); } @Override public void destroy() { } }
此處我列出一些相關網站