前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
PS:如果遇到 這個問題?Request header field Content-Type is not allowed by Access-Control-Allow-Headers,解決方法見另一博文:解決:Request header field Content-Type is not allowed by Access-Control-Allow-Headers
?
1. 場景描述:
我前端是一個 vue 工程,寫的是絕對 URL 請求后端工程接口,報錯如題:
No 'Access-Control-Allow-Origin' header is present on the requested resource
2.解決方法,后端開放跨域:新增一個過濾器,設置頭信息。
重點是這個設置:
response.setHeader("Access-Control-Allow-Origin", "*");
package gentle.filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 解決跨域設置* (可把此設置放在 nginx 中,但只能設置一處)** @author silence* @date 2018/12/11 15:19*/@WebFilter(filterName = "requestFilter", urlPatterns = {"/*"})
public class RequestFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) servletResponse;HttpServletRequest request = (HttpServletRequest) servletRequest;// 此處 setHeader、addHeader 方法都可用。但 addHeader時寫多個會報錯:“...,but only one is allowed”response.setHeader("Access-Control-Allow-Origin", "*");
// response.addHeader("Access-Control-Allow-Origin", request.getHeader("origin"));// 解決預請求(發送2次請求),此問題也可在 nginx 中作相似設置解決。response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Cache-Control,Pragma,Content-Type,Token, Content-Type");response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Credentials", "true");String method = request.getMethod();if (method.equalsIgnoreCase("OPTIONS")) {servletResponse.getOutputStream().write("Success".getBytes("utf-8"));} else {filterChain.doFilter(servletRequest, servletResponse);}}@Overridepublic void destroy() {}}
?再次請求,可以了。
?
3. 前后端工程也有作反向代理。前端工程部署時使用瀏覽器默認端口:80 。后端工程端口為 8089 。nginx 監聽端口 8082 。
前端請求后端 URL 為:http://? nginx所在服務器?IP : 8082?
前端工程請求 8082,nginx 收到請求再轉發到實際服務,取得數據,并最終再返回。
(nginx 所在服務器也就是代理服務器,可以和后端服務器為同一主機)
在 nginx 配置文件中設置為:
端口占用情況如下:紅框是 nginx 、黃框是前端工程、藍框是后端工程。
PS: springboot 項目中過濾器使用方法見文章:Springboot 項目中過濾器的使用
?
---------------------------------------------------------------------
后記 :解決報錯見文章 :springboot&ajax&has been blocked by CORS policy: No 'Access-Control-Allow-Origin
另報錯:The 'Access-Control-Allow-Origin' header contains multiple values'x, *', but only one is allowed.的解決方式見文章:
解決:The 'Access-Control-Allow-Origin' header contains multiple values'x, *', but only one is allowed.
---------------------------------------------------------------------
補記:
2019.5.16
作了以上配置后出現情況:跨域問題時好時不好,最后在 nginx 代理中加了一個假性集群配置:
這樣,請求后端成功。訪問正常。此處的 ergouzi 只是 upstream 的名字。
事實上后端工程項目只部署在 8089 上,其實 8082 上什么也沒有。
---------------------------------------------------------------------
補記:
2019.6.5
其實不用配置假性集群,之所以會出現上面時好時不好情況的原因僅是由于我隊友當時的操作:
他也用我服務器,那段時間有時會重啟他應用的服務,而當他重啟之前會執行命令:
ps -ef | grep java | awk '{print $2}' | xargs kill -9
查出當前運行的所有java程序再一并 kill ,
這樣我的服務也掛了,而我只注意到前端工程請求失敗,并未去查看后端工程服務是否正常。
好吧 ,這個我也應該檢討自己太粗心 ...
?
參考:https://blog.csdn.net/qq_39403545/article/details/82116121?