VueJS 向 Flask 發送 POST 失敗(CORS 請求被阻止)
我一直在關注這個vuejs 指南和這個燒瓶指南,將我的前端和後端託管在樹莓派上。
在我的前端,我有這個方法,它將 axios POST 發送到後端。
// path = http://127.0.0.1:5000/shift // pin, port = 1-8 / SER1 sendByte(pin, port) { console.debug(`Setting ${pin} on ${port}`); // I'm adding the header to the payload directly const payload = { data: { pin, port }, headers: { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json" } }; console.debug(payload); axios.post(this.paths.shift, payload); }
但是我的後端沒有收到有效負載(因為 uwsgi.log 中沒有任何有效負載),而是在控制台中收到此錯誤:
11:53:38.551 new-submission event fired Setup.vue:52 11:53:38.578 Watch-Handler for submissions fired (localStorage updated) Setup.vue:33 11:53:42.312 Setting 1 on SER1 Visualization.vue:83 11:53:42.313 Object { pin: 1, port: "SER1" } Visualization.vue:85 11:53:45.151 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5000/shift. (Reason: CORS request did not succeed). 2 11:53:45.154 Error: Network Error createError.js:16 11:53:46.351 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5000/togglePort. (Reason: CORS request did not succeed). 2 11:53:46.353 Error: Network Error createError.js:16
因為它與此錯誤最相關,所以這是我的 nginx.conf:
server { listen 80; server_name fire.com; charset utf-8; root /var/www/fire-extinguish-visualizer/dist; index index.html index.htm; # Always serve index.html for any request location / { try_files $uri /index.html @fireFlask; } location /static { root /var/www/fire-extinguish-visualizer/dist/; } location @fireFlask { include uwsgi_params; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' '*'; # uwsgi_pass unix:/var/www/fire-extinguish-visualizer/server/uwsgi.sock; # uwsgi_pass 127.0.0.1:5000; uwsgi_pass uwsgi://localhost:5000; } error_log /var/log/nginx/vue-app-error.log; access_log /var/log/nginx/vue-app-access.log; }
我已經嘗試了許多配置和設置,但我無法讓它工作。
在所有這些嘗試之後,我不想發布我嘗試過的每個 nginx.conf 或 uwsgi.ini,但是為了更好地衡量,我的相關文件在這個 gist中。
我的問題是:
如何在 SENDER 和 RECEIVER 端正確設置 CORS 以避免此錯誤?
據我了解,完成以下操作後它應該可以工作:
- Nginx 將 CORS 標頭添加到來自託管應用程序的 POST 請求
- uWSGI 配置正確
- Flask 應用程序已安裝 CORS 並允許跨域請求
那裡還有什麼?我現在只是對這個跨域錯誤感到困惑。
在 uwsgi.conf 中使用 http 時,我可以使用 curl 來獲得正確的響應:
pi@firepi:~ $ curl -X POST http://localhost:5000/togglePort -d '{"port":"SER1", "trigger":0}' -H 'Content-Type: application/json' {"status":"success"} pi@firepi:~ $ curl -X POST http://localhost:5000/shift -d '{"port":"SER1", "pin":1}' -H 'Content-Type: application/json' {"status":"success"}
嘗試帶有標題和來源的捲曲給出了這個:
pi@firepi:~ $ curl --include -X OPTIONS http://localhost:5000/togglePort -d '{"port":"SER1","trigger":0}' --header Access-Control-Request-Method:POST --header Access-Control-Request-Headers:Content-Type --header Origin:http://localhost:80 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Allow: OPTIONS, POST Access-Control-Allow-Origin: http://localhost:80 Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT Vary: Origin Content-Length: 0
我也偶然發現了uwsgi-tools,但我真的不知道如何使用 uwsgi_curl 發送特定的 CORS 標頭。不過,這將有助於解決此問題,因為我可以縮小範圍。有什麼想法嗎?
由於我的程式碼/配置中的 3 個錯誤配置而發生此問題。
更正 #1
正如@Slytherin 在評論中建議的那樣,為了使 Nginx 正常工作,我需要將 POST 發送到正確的埠。在我的 Vue-App 中,我已經程式將 POST 直接發送到 Flask-App,這會導致 CORS 錯誤,因為 Nginx 無法添加適當的標頭。我通過修復路徑來修復它:
... paths: { // This is a static Address. I later changed it to a hostname: firepi:80 togglePort: "http://192.168.137.139:80/togglePort", shift: "http://192.168.137.139:80/shift" } ...
需要注意的是,當
localhost
作為地址使用時,瀏覽器實際上會指向它自己。因此,如果您在伺服器 X 上執行您的應用程序並從 PC A 訪問它,則 localhost 的路徑實際上將在 PC A 中解析,而不是在伺服器 X 中。因此,建議使用正確設置的主機名。更正 #2
因為我的主要錯誤發生在問題 1(Nginx 埠)中,所以穩定地查看問題 2 是非常錯誤的。(CORS 配置)要啟用 CORS,我需要在Nginx 配置中添加正確的標頭,還需要配置我的 Flask-App 中的 CORS。對於 Flask,我只使用了預設值
CORS(app)
。在我的特殊情況下,我允許所有來源,因為此應用程序位於本地網路內,但在將應用程序連接到網際網路時,您應該明確限制此類訪問。
更正 #3
由於我將應用程序定向到埠 80 上的地址,因此我需要在 Nginx 中配置該連結:
location /togglePort { include uwsgi_params; uwsgi_pass unix:/var/www/fire-extinguish-visualizer/server/app_uwsgi.sock; } location /shift { include uwsgi_params; uwsgi_pass unix:/var/www/fire-extinguish-visualizer/server/app_uwsgi.sock; }