場景:在實現一個小demo,前後端是分開的,前端使用了angularjs 中的 $http 去訪問後端接口,發現 $http().success() 方法一直沒有執行,後來在瀏覽器中看到發送 http請求後報錯了,後來發現是因爲跨域問題,主流瀏覽器出於安全考慮對跨域做了處理,最後我解決辦法是在後端添加一些代碼。
接下來是問題的發現和解決思路:
1、報錯
在谷歌瀏覽器的報錯:
Access to XMLHttpRequest at 'http://10.8.1.32:8080/updateClient/saveHPP2' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
在火狐瀏覽器的報錯:
截跨源請求:同源策略禁止讀取位於 http://10.8.1.32:8080/updateClient/saveHPP2 的遠程資源。(原因:CORS 頭缺少 'Access-Control-Allow-Origin')。
2、原因
CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與服務器應該如何溝通。CORS背後的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功還是失敗。
換句話說,就是服務器在響應頭裏設置好允許哪些地址訪問(通過Access-Control-Allow-Origin
設置),當瀏覽器收到服務端響應時,查看這個字段,如果包含請求方的地址或設置爲了*
,則允許此次跨域。
3、前端請求代碼:
app.service('mService', function($http){
this.saveHomePagePicture = function(formData, url){
return $http({
method: 'POST',
url: url,
data: formData,
headers: {'Content-Type':undefined},
transformRequest: angular.identity
})
}
})
4、後端添加一個 Filter 進行處理
@Component
public class CorsFilter implements Filter{
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest reqs = (HttpServletRequest) req;
// response.setHeader("Access-Control-Allow-Origin",reqs.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
參考網址:
已攔截跨源請求:同源策略禁止讀取位於 http:**** 的遠程資源。(原因:CORS 頭缺少 'Access-Control-A
https://blog.csdn.net/qq_41377914/article/details/79181006
angularjs中的$http詳解:
https://blog.csdn.net/qq_30638831/article/details/77688014
Spring Boot如何解決前端的Access-Control-Allow-Origin跨域問題:
https://blog.csdn.net/tiangongkaiwu152368/article/details/81099169
angularjs跨域post解決方案