如何仅使用 dart 代码解决 flutter web api cors 错误?

tsi*_*ixe 9 api http request dart flutter

似乎 CORS 错误是网络领域的众所周知的问题。但是我有史以来第一次尝试了 flutter web,我遇到了严重的错误。

下面的代码在 iOS 设备上运行时在应用程序版本中运行良好,但是当我在 Chrome 上使用 beta 通道的网络调试测试相同的代码时,它遇到了 CORS 错误。

其他 stackoverflow 答案解释了如何使用其项目的服务器端文件解决 CORS 问题。但我完全不知道什么是服务器问题以及如何处理他们的答案。来自 Chrome 控制台的错误消息如下

[从源 'http://localhost:52700' 访问 XMLHttpRequest at 'https://kapi.kakao.com/v1/payment/ready' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。]

所以,我想要做的是仅使用 DART 代码解决上面的“Access-Control-Allow-Origin 标头”问题!下面的代码是我尝试仅使用 main.dart 解决这些问题的代码。

onPressed: () async {
      var res =
          await http.post('https://kapi.kakao.com/v1/payment/ready', encoding: Encoding.getByName('utf8'), headers: {
        'Authorization': 'KakaoAK $_ADMIN_KEY',
        HttpHeaders.authorizationHeader: 'KakaoAK $_ADMIN_KEY',
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "POST, GET, OPTIONS, PUT, DELETE, HEAD",
      }, body: {
        'cid': 'TC0ONETIME',
        'partner_order_id': 'partner_order_id',
        'partner_user_id': 'partner_user_id',
        'item_name': 'cool_beer',
        'quantity': '1',
        'total_amount': '22222',
        'vat_amount': '2222',
        'tax_free_amount': '0',
        'approval_url': '$_URL/kakaopayment',
        'fail_url': '$_URL/kakaopayment',
        'cancel_url': '$_URL/kakaopayment'
      });
      Map<String, dynamic> result = json.decode(res.body);
      print(result);
    },
Run Code Online (Sandbox Code Playgroud)

尽管我实际上有"Access-Control-Allow-Origin": "*"大多数其他答案推荐的标题,但 Chrome 控制台打印了相同的错误消息。奇怪的是,相同的代码在 mobileApp 版本中发出了成功的请求。所以我认为这只是 flutter WEB VERSION 的问题。

希望有人能弄清楚并建议仅使用 dart 代码来解决我的 main.dart 中的问题!!感谢您阅读 [:

Use*_*ebo 126

从 Flutter 3.3.0 开始

我实现了向 flutter 命令添加任何浏览器标志的选项。

flutter run -d chrome --web-browser-flag "--disable-web-security"
Run Code Online (Sandbox Code Playgroud)

或者对于drive命令:

flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d web-server --web-browser-flag="--disable-web-security"
Run Code Online (Sandbox Code Playgroud)

注意:这仅用于开发测试。Flutter是在客户端浏览器上显式执行的!您不应该也不能在生产中禁用它(如 @Tommy 所述),因为它是浏览器的一项安全功能,并不意味着在 dart 代码中进行更改。您必须在提供 Flutter 应用程序资源的Web 服务器上启用 CORS ,以确保它适用于每个人。

如果您在带有架子的服务器端使用没有 Flutter 的dart 语言,则可以看到此响应

  • 您可以将 `args` 添加到您的[启动配置](https://docs.flutter.dev/development/tools/vs-code#run-app-in-debug-profile-or-release-mode):`{ “名称”:...,“请求”:“启动”,“类型”:“dart”,“参数”:[“--web-browser-flag=--disable-web-security”]}` (10认同)

Osm*_*zcu 43

1- 转到 flutter\bin\cache 并删除名为:flutter_tools.stamp 的文件

2- 转到 flutter\packages\flutter_tools\lib\src\web 并打开文件 chrome.dart。

3- 找到“--disable-extensions”

4- 添加'--disable-web-security'

  • :( 部署到生产环境时,再次显示错误 (40认同)
  • 我认为这个解决方案不适合我。但后来我注意到我没有在“--disable-web-security”后面加逗号 (11认同)
  • 别担心@Becca,因为这仅适用于您的本地,没有cors。 (4认同)
  • 对于 Linux 我来说,文件位于 `~/snap/flutter/common/flutter/packages/flutter_tools/lib/src/web/chrome.dart` 顺便说一句 (4认同)
  • 这有效。谢谢您,但我收到此警告“您正在使用不受支持的注释行...稳定性和安全性将受到影响。”,我应该担心吗? (3认同)
  • 不适用于已发布的 flutter web 构建 - (3认同)
  • 另一个文件:`sudo rm ~/snap/flutter/common/flutter/bin/cache/flutter_tools.stamp` (2认同)
  • 自 flutter 3.3.0 以来,不再需要奇怪的解决方法,您可以在 flutter 命令中添加任何 Web 浏览器标志,请参阅:/sf/answers/5234839991/ (2认同)

小智 25

我认为按照建议禁用网络安全将使您暂时跳过当前错误,但是当您在其他设备上进行生产或测试时,问题将持续存在,因为这只是一种解决方法,正确的解决方案是从服务器端允许 CORS来自请求域并允许所需的方法和凭据(如果需要)。


Ali*_*aza 14

这是 CORS(跨域资源共享)问题,您不必删除/修改任何内容。您只需从服务器端启用 CORS 请求即可正常工作。

就我而言,我已经使用 node.js 和express.js 创建了一个服务器,因此我只是添加了这个将为每个请求运行的中间件函数。

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,PUT,PATCH,POST,DELETE");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
Run Code Online (Sandbox Code Playgroud)

还有嘭!我收到了数据。

您只需查看设置即可为您的服务器启用 CORS。


Pra*_*att 10

使用 web-renderer 运行/编译您的 Flutter Web 项目。这应该可以解决本地和远程问题:

flutter run -d chrome --web-renderer html
flutter build web --web-renderer html
Run Code Online (Sandbox Code Playgroud)

  • 不进行远程工作 (5认同)
  • 不从事本地或生产工作。 (4认同)

CNK*_*CNK 8

经过几个小时的测试,以下内容对我来说非常有效。

将以下内容添加到 PHP 文件中:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With");
Run Code Online (Sandbox Code Playgroud)

这允许与 HTTP GET POST 的正确连接,对我来说不会出现 flutter 问题。

我在以下讨论中发现了这一点:

XMLHttpRequest 错误颤振


Bob*_*bin 7

如果您运行 Spring Boot 服务器,请将“@CrossOrigin”添加到您的控制器或服务方法中。

@CrossOrigin
@PostMapping(path="/upload")
public @ResponseBody ResponseEntity<Void> upload(@RequestBody Object object) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我知道这个问题明确要求仅“使用 dart 代码”解决方案,但我无法使用 dart 代码修复异常(例如通过更改标头)。


tsi*_*ixe 6

2023 年 3 月更新

我在谷歌云上使用谷歌云函数v2来运行我的函数。我不是在我的 flutter 客户端中调用 CORS 敏感的 api 或运行整个 Node js 客户端应用程序,而是调用用 js 编写的函数(在 google Cloud Functions v2 Node js 18 env 上运行)。这样唯一调用google cloud run的http.dart将成为flutter client的主进程,这将有助于解决原来的问题。当然,使用 google cloud run 是需要付费的,但我相信运行我们服务的全部功能的费用是相当合理的 [:


确实需要像 Node js 或 django 这样的服务器端引擎来使用带有大量外部 API 的 Flutter Web。实际上,由于与端口号差异相关的 CORS 机制,当我们尝试使用内部 api 时,很有可能出现相同的 CORS 错误。

SO 贡献者提供了很多建议使用 chrome 扩展来避免 CORS 错误的步骤和答案,但这对用户来说实际上并不酷。所有用户都应该下载浏览器扩展才能使用我们的单个网站,如果我们使用真正的服务器引擎,就不会存在该网站。

据我所知,CORS 来自浏览器,因此我们具有相同 api 代码的 flutter ios 和 android 应用程序不会给出这些 CORS 错误。我第一次在 flutter web 中遇到这个错误时,我相信我可以在我的应用程序代码行中处理 CORS。但这对于用户和长期开发计划来说实际上并不是健康的方式。

希望所有 Flutter Web 新手都明白 Web 对我们来说是一个相当狂野的领域。尽管我也是新手,但我强烈建议所有从 1.22.n 稳定版开始的 Flutter Web 开发人员学习 Node js 等服务器端引擎。值得一试。

如果你已经了解了我的自我回答,这里有一个使用 Node js 的 Flutter Web 的简单指南。Flutter Web 处于稳定渠道,但所有必要的基础设施对于像我这样的新手来说还没有完全准备好。因此,当你第一次涉足 Web 领域时要小心,并希望你重新检查所有条件和要求,以确定你是否真的需要 Flutter 应用程序的 Web 版本,以及你是否真的需要使用 Flutter 来完成这项工作。我的回答是肯定的哈哈

https://blog.logrocket.com/flutter-web-app-node-js/


Tim*_*m R 6

禁用网络安全方法在开发中效果很好,但在生产中可能不太好。在生产 dart 代码中对我有用的一种方法是通过保持 Web 请求简单来完全避免飞行前的 CORS 检查。就我而言,这意味着更改请求标头以包含:

'Content-Type': 'text/plain'
Run Code Online (Sandbox Code Playgroud)

尽管我实际上发送的是 json,但将其设置为 text/plain 可以避免飞行前的 CORS 检查。我调用的 lambda 函数不支持飞行前 OPTIONS 请求。

以下是有关保持请求简单并避免飞行前请求的其他方法的一些信息