【问题标题】:How to solve flutter web api cors error only with dart code?如何仅使用 dart 代码解决颤振 Web api cors 错误?
【发布时间】:2021-04-14 06:19:57
【问题描述】:

似乎 CORS 错误在网络领域是众所周知的问题。但我第一次尝试使用 Flutter Web 时遇到了严重错误。

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

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

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

所以,我要做的是仅使用 DART 代码解决上述“访问控制允许来源标题”问题!下面的代码是我尝试仅使用 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);
    },

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

希望有人能解决这个问题并建议 only-dart 代码来解决我的 main.dart 中的问题!感谢您阅读[:

【问题讨论】:

  • 在这种情况下,我认为您应该在服务器端启用它。您是否尝试过 ngrok 为您的应用程序提供服务,看看它是否可以这样工作?可能是服务器不允许localhost
  • 这是小问题。现在我知道为什么网络开发人员会为我的问题按下拇指。我在带有关键字“flutter with node js”的中等文章之后添加了简单的节点 js,它运行良好。我们需要服务器端附加组件来使 Flutter Web 与这些 api 一起工作。希望来自 Flutter 1.22.n 的 web 新手明白,我们确实需要像节点引擎这样的服务器来使用 flutter web 的 api
  • 这可能是您正在寻找的解决方案stackoverflow.com/a/37765371/13758642

标签: api flutter http dart request


【解决方案1】:

我认为您可能没有以正确的方式执行此操作。 cors 标头应该添加到 HTTP 响应标头中,而您显然将它们添加到您的 reuqest 标头中。

有关更多信息,请查看文档https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#what_requests_use_cors

【讨论】:

    【解决方案2】:

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

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

    3- 查找'--disable-extensions'

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

    【讨论】:

    • 这行得通。谢谢,但我收到此警告“您正在使用不受支持的评论行...稳定性和安全性将受到影响。”,我应该担心吗?
    • 别担心@Becca,因为这仅适用于您的本地没有 cors。
    • 对于 Linux 我来说,文件位于 ~/snap/flutter/common/flutter/packages/flutter_tools/lib/src/web/chrome.dart BTW
    • 还有另一个文件:sudo rm ~/snap/flutter/common/flutter/bin/cache/flutter_tools.stamp
    • 我也想知道,你到底是怎么找到这个解决方案的?它对我有用!
    【解决方案3】:

    确实需要像 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 stable 的 Flutter Web 开发人员来学习像 node js 这样的服务器端引擎。值得一试。

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

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

    【讨论】:

    • 那么当你使用 Firebase 作为后端时,我们怎么办?!
    • @SIMMORSAL 我不太确定与 Firebase 相关的错误是什么。结合 node js 引擎和 Firebase 产品,我还没有让自己走得太远。但是,如果您在某种情况下确实解决了错误,那么可能会打开一个新的 SO 线程,其中包含 flutter-web、cors、firebase 和 firebase- 等标签,如果您发表评论将不胜感激新线程的链接在这里 [:
    • 我发现了问题stackoverflow.com/a/67830000/4457315 ... Thaanks 反正。
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

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

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

      3- 查找'--disable-extensions'

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

      5- 添加'--user-data-dir=/Users/mt/Desktop/chromedata'

      【讨论】:

        【解决方案6】:

        更新

        我建议使用Rexios's answer。他的包使得修改Flutter源码非常方便。


        MacOS & Android Studio 的替代解决方案(无需修改 Flutter 源代码)

        我们使用与 Osman Tuzcu 类似的方法。我们没有修改 Flutter 源代码,而是在 shell 脚本中添加 --disable-web-security 参数,并转发 Flutter 设置的所有其他参数。它可能看起来过于复杂,但只需要一分钟,并且不需要为每个 Flutter 版本重复。

        1。在终端中运行它

        echo '#!/bin/zsh
        # See also https://stackoverflow.com/a/31150244/410996
        trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
        set -e ; /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --test-type --disable-web-security "$@" ; set +e &
        PID=$!
        wait $PID
        trap - SIGINT SIGTERM EXIT
        wait $PID
        ' > ~/chrome_launcher
        
        chmod 755 ~/chrome_launcher
        

        这会将chrome_launcher 脚本添加到您的用户文件夹并将其标记为可执行。

        2。将此行添加到您的 .zshrc(或 .bashrc 等):

        export CHROME_EXECUTABLE=~/chrome_launcher
        

        3。重启 Android Studio

        如果简单重启不起作用,请在 Android Studio 中使用 Invalidate Caches / Restart 强制加载更改。

        注意事项

        该脚本还添加了--test-type 标志以抑制有关已禁用安全功能的丑陋警告。请注意,此选项也可能会抑制其他错误消息! CHROME_EXECUTABLE 仅采用可执行文件的路径,无法在此处设置参数。 在不捕获退出信号并终止进程组的情况下,当您在 Android Studio 中点击 Stop Button 时,Google Chrome 实例不会被终止。

        【讨论】:

          【解决方案7】:

          使用Osman Tuzcu 的回答,我创建了flutter_cors 以简化流程。

          【讨论】:

          • 酷!谢谢[:
          【解决方案8】:

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

          flutter run -d chrome --web-renderer html
          flutter build web --web-renderer html
          

          【讨论】:

            猜你喜欢
            • 2021-11-05
            • 2021-07-11
            • 2021-05-12
            • 2020-12-16
            • 2022-09-14
            • 2021-05-02
            • 2021-09-12
            • 2021-09-17
            • 2021-10-07
            相关资源
            最近更新 更多