在 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 上禁用 CORS

如何在 Flutter Web 上禁用 SPA

只有在 Flutter 应用程序上使用 Web 时,如何才能禁用某些功能?

Flutter Web - TextFormField 禁用复制和粘贴

Flutter web,禁用Tab按下按钮上的焦点

如何在flutter中登录后禁用用户返回