1. 程式人生 > 其它 >前後端分離導致跨域問題處理

前後端分離導致跨域問題處理

技術標籤:javawebjavajavascript

前後端分離導致跨域問題處理


前言

前後端專案分離,專案部署的時候會產生跨域的問題,本文梳理了跨域產生的原因和如何處理跨域問題。


一、跨域是什麼?

當一個請求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