‘Access-Control-Allow-Origin‘ heade is present on the requested 跨域問題 解決
阿新 • • 發佈:2020-12-24
'Access-Control-Allow-Origin' heade is present on the requested 跨域問題 解決
1、解決問題前先確定是不是跨域
遇到這個問題首先要明確一點,就是你是不是真的跨域,因為在請求的過程中,前後端一些其它的問題,即使不是跨域,瀏覽器Console中也會報同樣的錯誤,讓你誤以為是跨域。所以,在解決這個問題之前你先確定是不是真的跨域。
2、什麼是跨域
跨域,是指瀏覽器不能執行其他網站的指令碼。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript實施的安全限制。
這裡說明一下,無法跨域是瀏覽器對於使用者安全的考慮,如果自己寫個沒有同源策略的瀏覽器,完全不用考慮跨域問題了。是瀏覽器的鍋,對。
同源策略限制了一下行為:
Cookie、LocalStorage 和 IndexDB 無法讀取
DOM 和 JS 物件無法獲取
Ajax請求傳送不出去
3、為什麼會跨域
跨域的原因是因為瀏覽器的同源策略導致的,當我們的前端工程部署的地址和後端的地址不同時,就會發生跨域。
前端發起的請求會帶上一個請求頭:Access-Control-Allow-Origin: http://www-dev.aitscs.enjoyor.net 冒號後面的是請求端的地址;
同時後端返回訊息,同時會帶上同樣的返回頭,但是帶的是自己後端服務的地址,瀏覽器接收到之後一對比發現不對啊,你們不一樣,為了安全起見,不能讓你們見面!所以就報錯了。
4、解決方法
之前也在網上找,說在後端加上過濾器設定請求頭為*
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "*");
但是這樣還是不行,瀏覽器會說不允許將這個請求頭設定為*
於是我想著把request的請求頭拿出來,給resquest
response.setHeader("Access-Control-Allow-Credentials" , "true");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
結果真的可以!
也可以通過本地配置nginx,再nginx中這隻請求頭,其實是一樣的,一般服務放在伺服器上的時候,都是會在nginx上配置請求頭的。
最後附上我的完整程式碼
@WebFilter(urlPatterns = "/*", filterName = "crosFilter")
public class CORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.addHeader("Access-Control-Allow-Headers"," Access-Control-Allow-Headers,Token,Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}