前後端分離導致跨域問題處理
阿新 • • 發佈:2020-12-12
前後端分離導致跨域問題處理
前言
前後端專案分離,專案部署的時候會產生跨域的問題,本文梳理了跨域產生的原因和如何處理跨域問題。
一、跨域是什麼?
當一個請求url的協議、域名、埠三者之間任意一個與當前頁面url不同即為跨域
當前頁面url | 被請求頁面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(協議、域名、埠號相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 協議不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 埠號不同(8080/7001) |
二、跨域瀏覽器報錯
三、跨域解決方案
1. 自建專案如何解決跨域
1.1 servlet專案
a. 單個請求處理方案
針對某個servlet裡面的doPost或者doGet方法,按照下面的程式碼,在業務邏輯前面新增。
/* 允許跨域的主機地址 */
response.setHeader("Access-Control-Allow-Origin", "*");
/* 允許跨域的請求方法GET, POST, HEAD 等 */
response.setHeader("Access-Control-Allow-Methods", "*");
/* 允許跨域的請求頭 */
response.setHeader("Access-Control-Allow-Headers", "*");
b. 全部請求處理方案
針對整個專案的全部請求,按照如下操作
1) 定義過濾器介面Filter的實現類,實現類中修改respone的頭資訊,把 “Access-Control-Allow-Origin” 的域名修改問請求方的域名,如下:
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class CORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "<請求方域名如:http://www.sohu.com>");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
2) 在web.xml中配置此過濾器:
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>filter.CORSFilter</filter-class>
</filter>
1.2 springboot專案
1.2.1 建立一個filter解決跨域。
@Component
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
1.2.2 使用@CrossOrigin這個註解在controller類中使用
@CrossOrigin(origins = "http://192.168.1.10:8080", maxAge = 3600)
@RequestMapping("rest_index")
@RestController
public class IndexController{
2. 公司專案如何解決跨域
2.1 uap專案
2.1.1 在main.js中,配置資料所在伺服器的字首(即固定部分),程式碼如下:
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api' //關鍵程式碼
關鍵程式碼:axios.defaults.baseURL = ‘/api’,作用是我們每次傳送的請求都會帶一個/api的字首。
2.1.2 在config資料夾下的index.js檔案中的proxyTable欄位中,作如下處理:
dev: {
env: require('./dev.env'),
port: 8090,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target:'http://api.douban.com/v2', // 你請求的第三方介面
changeOrigin:true, // 在本地會建立一個虛擬服務端,然後傳送請求的資料,並同時接收請求的資料,這樣服務端和服務端進行資料的互動就不會有跨域問題
pathRewrite:{ // 路徑重寫,
'^/api': '' // 替換target中的請求地址,也就是說以後你在請求http://api.douban.com/v2/XXXXX這個地址的時候直接寫成/api即可。
}
}
},
cssSourceMap: false
}
2.1.3 在具體使用axios的地方,修改url如下即可:
axios.get("/movie/top250").then((res) => {
res = res.data
if (res.errno === ERR_OK) {
this.themeList=res.data;
}
}).catch((error) => {
console.warn(error)
})
2.2 基建專案
基建專案採用公司v7平臺,底層是 servlet架構,採用上面servlet的解決方案。
2.3 雲監理專案
雲監理專案屬於網際網路專案,通過nginx轉發的方式實現。
location /hussarApi/ {
proxy_pass http://yjl.taimohongcheng.com:9999;
}
location /wx/ {
proxy_pass http://yjl.taimohongcheng.com:9001;
}
2.4 輕騎兵v8
refer-whitelist: # 使用前後分離,需要配置前端請求的白名單,防止跨域請求後臺,例如前臺請求地址為:http://192.168.6.14:8081/ 此處就配置為http://192.168.6.14:8081/
- http://localhost:8082/
- http://localhost:8081/
- http://localhost:8088/
- http://localhost:8089/
- http://loaclhost:8082/
- http://localhost:8080/
- http://zwyjl.taimohongcheng.com:8080/
總結
以上就是今天要講的內容,本文僅僅簡單介紹了幾種比較通用的解決跨域的方法。希望通過本次內容的講解,能讓大家今後對此類問題有一個更加清晰的認識和解決方案。
參考資料
https://blog.csdn.net/wh_xmy/article/details/87705840
https://www.cnblogs.com/diandianquanquan/p/10607102.html
https://blog.csdn.net/wangxin1982314/article/details/50249543
https://www.cnblogs.com/zgrey/p/13972270.html