在 Flutter 上禁用 CORS
Posted
技术标签:
【中文标题】在 Flutter 上禁用 CORS【英文标题】:Disable CORS on Flutter 【发布时间】:2021-06-29 08:52:24 【问题描述】:即使有一些关于 Flutter 的 CORS 问题的帖子/问题,我仍然无法使用可用的解决方案来修复它,其中主要涉及在服务器端修复它。就我而言,我无权访问服务器/API。此外,要求第三方更改其服务非常困难,因为在使用 Python 和 VBA 等其他框架/语言进行测试时,从 API 获取数据以及使用 INSOMNIA 测试都没有问题。
所以,我的想法是,由于某种原因,颤振正在触发 CORS,是否可以根据请求“禁用”它?
我得到的错误是:
在“https://yyy.ytr.com.xx/xxx/xxx/xx/zzzzz”访问 XMLHttpRequest 来自原点“http://localhost:56659”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。
如果我在本地禁用 CORS,它可以工作,但显然,它在部署时会失败。
这是我目前在 Flutter 中执行请求的方式。
else
final response = await http.post(Uri.parse(API),
body: json.encode(
"key": Key,
"user": User,
"pass": Pass,
),
headers: <String, String>'Content-type': 'application/json');
谢谢,
【问题讨论】:
【参考方案1】:就我而言,我无权访问服务器/API。此外,要求第三方更改其服务非常困难,因为在使用 Python 和 VBA 等其他框架/语言进行测试时,从 API 获取数据没有问题
这个第三方在编写 API 方面听起来不是很有经验。我会重新考虑与他们合作。
您无法“修复”CORS。任何在浏览器中运行的网站都会受到此限制,无论它是用 Dart 还是 Flutter 或其他东西编写的。
如果您有可以访问这个不专业的 API,而您有编写了一个网站来这样做,那么您就不走运了。这是不可能的。
你的选择是:
让 API 提供商修复他们的服务器设置 使用 Flutter 编写实际的桌面或移动应用程序而不是网站【讨论】:
你是对的。我的另一个选择是用 VBA 在 Excel 中编写这个,这让我不寒而栗。如果远程部署不是问题,则可以使用桌面解决方案。对后者有什么想法吗?【参考方案2】:我在这个问题上遇到了很多麻烦。有些人会告诉你禁用 chromuim 上的 cors。但这不是一个好的做法,因为您不会告诉不懂技术的人在没有 cors 的情况下启动他的浏览器。这将使您的应用非常难以使用,并使其不安全。
这就是为什么在第 3 方 API 端执行此操作对您很重要。您可以要求您的 API 提供商将您的前端服务器 IP 添加到他的 cors 白名单中。
至于我自己的情况,我使用的是 odoo 12,然后我发现 cors 在那里重写并不容易。这就是为什么我安装了一个简单的 nginx,我允许我的 Flutter 前端应用程序使用 cors。我的后端应用程序在端口 9092 上,您可以将其调整到任何其他后端服务器。但是在它工作之后,不要忘记限制对 CORS 的访问。
这是我的相关 nginx 配置:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events
worker_connections 1024;
http
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream odooserver
server 127.0.0.1:9092;
map $http_origin:$host $origin
default "";
http://localhost:9092 $http_origin;
server
listen 80;
server_name domainname.com;
access_log C:/nginx-1.20.1/logs/testing-access.log;
error_log C:/nginx-1.20.1/logs/testing-error.log;
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
location /
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header Access-Control-Allow-Origin;
if ($request_method = 'OPTIONS')
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' '*' always;
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
if ($request_method = 'POST')
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
add_header 'Access-Control-Expose-Headers' '*' always;
if ($request_method = 'GET')
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
add_header 'Access-Control-Expose-Headers' '*' always;
proxy_redirect off;
proxy_pass http://odooserver;
location ~* /web/static/
proxy_cache_valid 200 90m;
proxy_buffering on;
expires 864000;
proxy_pass http://odooserver;
gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
gzip on;
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location /
# root html;
# index index.html index.htm;
#
#
# HTTPS server
#
#server
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location /
# root html;
# index index.html index.htm;
#
#
**strong text**
【讨论】:
【参考方案3】:CORS 是一种安全措施,您不应被禁用。相反,您应该调整 CORS 规则。
如果您仍然坚持禁用 CORS(因为它仅用于开发),请关注此线程:https://github.com/flutter/flutter/issues/46904
TL;DR,您必须在浏览器中禁用它。
这里有一个很好的 CORS 解释:https://gist.github.com/jesperorb/6ca596217c8dfba237744966c2b5ab1e
【讨论】:
tks,@mightybruno。也许我没有正确表达自己。但是当我说禁用它时,我的意思是不要用 Flutter 触发 CORS。此外,在本地我能够测试它是否禁用,这并不理想,因为一旦部署该问题仍然存在。 请看我回答的第二段和第三段。另外,我建议您阅读我发布的最后一个链接的内容。 Tks @mightbruno,我希望 JSONP 可以工作,但它似乎只适用于 GET 方法,但不适用于 POST,这是我的情况。以上是关于在 Flutter 上禁用 CORS的主要内容,如果未能解决你的问题,请参考以下文章
只有在 Flutter 应用程序上使用 Web 时,如何才能禁用某些功能?