[英]CORS error on request, with headers and webpack-dev-server proxy configured
我最近幾天一直在設計一個簡單的 ReactJS+Typescript 應用程序(與 Webpack 捆綁在一起)。 現在,我開始了后端連接部分(不是我的領域,也不是我在這種情況下的責任),我遇到了一些困難。 主要問題是瀏覽器上出現 CORS 錯誤。 這是我的設置:
"webpack": "^4.30.0",
"webpack-dev-server": "^3.3.1",
"typescript": "^3.4.5",
"react": "^16.8.6",
"axios": "^0.18.0",
Chrome version 74.0.3729.131 (64-bit)
我已經嘗試了幾件事來解決這個問題,但沒有一個真正解決了這個問題。 它們如下:
webpack.dev.ts
配置文件中,我配置了 webpack 代理屬性。 我是這樣配置的: devServer: {
contentBase: path.join(__dirname, process.env.PUBLIC_PATH || '../dist'),
compress: true,
host: process.env.DEV_HOST || 'localhost',
port: process.env.DEV_PORT || 8000,
open: 'chrome',
proxy: {
'/api': {
target: 'http://<ip>:8888',
secure: false,
},
},
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
},
},
對后端的請求構建如下:
const config = {
method: 'post',
url: '/api/login',
data: { password: password },
};
axios(config)
.then(resp => console.log(resp))
.catch(error => console.log(error));
請注意,目前, password
字段只是一個占位符,不會在后端進行驗證,因此不需要Access-Control-Allow-Credentials
header。
令我非常失望的是,該請求似乎沒有使用配置的代理,因為這是錯誤:
在網絡選項卡上,也沒有提及后端 IP 地址。 請注意,只有在這種情況下,請求才會顯示為POST而不是OPTIONS請求。
axios
。 這也沒有帶來任何解決方案。 這就是我想出的:const config = {
method: 'post',
url: 'http://<ip>:8888/api/login',
data: { password: password },
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
},
};
axios(config)
.then(resp => console.log(resp))
.catch(error => console.log(error));
出現的結果類似於沒有任何配置的結果(此處附上第一張圖片)。
Access-Control-Allow-Origin: *
header 附加到所有請求。 這就是事情變得有趣/奇怪的地方。 在此擴展處於活動狀態(並且未對其進行配置)的情況下,即使我禁用了所有其他先前的選項,錯誤也會發生變化:我也嘗試過同時激活所有三個先前的選項,最后一個錯誤就是出現的。
我不確定下一步要去哪里,或者如何從這里開始。 我避免請求更改服務器 API 的標頭,但作為最后的手段,我保持該選項處於打開狀態。
我已嘗試對解釋和我想要實現的目標進行徹底的解釋,但請隨時索取更多信息。
提前致謝。
畢竟,我別無選擇,只能在收到預檢( OPTIONS )請求時用幾個標頭更新后端:
Access-Control-Allow-Headers
,其中包含請求在同一標頭上的任何內容;Access-Control-Allow-Origin
,設置為*
。 由於在生產中,前端和后端都是本地的,這將僅用於我們的開發環境;Access-Control-Allow-Methods
,為了方便將其設置為*
。 我們可以指定在我們允許的域上允許哪些方法,但我們認為這對於開發環境來說不是必需的。設置這些標志后,我將代理配置保留在 Webpack 上,如下所示:
proxy: {
'/api': {
target: 'http://<ip>:8888',
secure: false,
},
},
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
},
重新測試我們的請求,一切都很順利。 我們發現沒有辦法僅在客戶端執行此操作。
謝謝大家的評論。
從加載 Web 應用程序的同一來源公開 API 后端服務器有助於繞過 CORS 限制。 這就是 webpack 開發服務器代理派上用場的地方。 首先,確保對 API 的請求尋址代理。 如果 XMLHttpRequest 或在源代碼地址中獲取絕對 URL(相對於相對 URL),則使用指示開發模式的標志來選擇代理作為源。 例如:
fetch(isDevelopment ? '/api' : 'http://backend.server.com/api')
.then(response => processResponse(response));
其次,配置代理以針對真實后端服務器上的所需 API:
devServer: {
proxy: {
'/api': {
target: 'http://backend.server.com'
}
}
}
從瀏覽器的角度來看,不再有跨域請求。 此配置也可能足以讓服務器正確響應(例如 Jetty 9 及其 CORS 過濾器集對我來說很好用)。 另一方面,即使是同源請求,瀏覽器也可能會發送Origin
標頭。 為了防止不同后端服務器上的 CORS 問題,如果有的話,請更改Origin
標頭以匹配目標 URL,如下所示:
devServer: {
proxy: {
'/api': {
target: 'http://backend.server.com',
onProxyReq: proxyReq => {
if (proxyReq.getHeader('origin')) {
proxyReq.setHeader('origin', 'http://backend.server.com');
}
}
}
}
}
有關更多信息,請參閱dev-server和它在后台使用的http-proxy-middleware庫的文檔。 此外,像 Wireshark 這樣的 TCP/HTTP 嗅探器非常有助於了解發送的內容以及響應發送的內容。
由於響應標頭中不存在access-control-allow-origin
標頭,因此您可以在代理設置中強制使用一個:
proxy: {
'/api': {
target: 'http://<ip>:8888',
secure: false,
onProxyRes: response => {
response.headers['access-control-allow-origin'] = 'http://localhost:8000';
},
},
},
這意味着所有代理響應都將具有此標頭。 這個onProxyRes
是http-proxy-middleware
東西,來源: https : //github.com/chimurai/http-proxy-middleware/blob/master/recipes/proxy-events.md
將changeOrigin
設置為true
。 請參閱下面的鏈接。
proxy: {
'/api': {
target: 'http://<ip>:8888',
secure: false,
changeOrigin: true,
},
},
https://webpack.js.org/configuration/dev-server/#devserverproxy
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.