如何仅使用 dart 代码解决 flutter web api cors 错误?
How to solve flutter web api cors error only with dart code?
CORS 错误似乎是网络领域的 well-known 问题。但是我第一次尝试 flutter web 时遇到了严重错误。
下面的代码在 运行 在 iOS 设备上时在应用程序版本中运行良好,但是当我在 Chrome 上测试相同的代码并从 beta 通道进行网络调试时,它遇到 CORS 错误。
其他 Whosebug 答案解释了如何解决他们项目的服务器端文件的 CORS 问题。但我完全不知道什么是服务器,也不知道如何处理他们的回答。来自 Chrome 控制台的错误消息低于
[从源 'http://localhost:52700' 访问位于 'https://kapi.kakao.com/v1/payment/ready' 的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' header 出现在请求的资源上。 ]
所以,我想做的是仅使用 DART 代码解决上述 'Access-Control-Allow-Origin header' 问题!下面的代码是我试图用 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);
},
尽管我实际上有大多数其他答案推荐的 header "Access-Control-Allow-Origin": "*"
,但 Chrome 控制台打印了相同的错误消息。奇怪的是,相同的代码在 mobileApp 版本中发出了成功的请求。所以我认为这只是 flutter WEB 版本的问题。
希望有人能解决并建议 only-dart 代码来解决我 main.dart 中的问题!!感谢您阅读 [:
我认为你这样做的方式可能不对。
cors headers 应该添加到 HTTP 响应 header 中,而你显然在 reuqest header 中添加了它们。
有关详细信息,请查看文档 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#what_requests_use_cors
1- 转到 flutter\bin\cache
并删除名为:flutter_tools.stamp
的文件
2- 转到 flutter\packages\flutter_tools\lib\src\web
并打开文件 chrome.dart
。
3- 查找'--disable-extensions'
4- 添加 '--disable-web-security'
真正需要像 node js 或 django 这样的服务器端引擎来使用带有一堆外部 apis 的 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 开发人员,以稳定地学习节点 js 等服务器端引擎。值得一试。
如果您一直到我的自我回答的这一行,这里有一个使用节点 js 的 flutter web 的简单指南。 Flutter web 处于稳定状态,但所有必要的基础设施还没有为像我这样的新手准备好。所以当你第一次涉足 web 领域时要小心,并希望你重新检查所有条件和要求,以确定你是否真的需要你的 flutter 应用程序的 web 版本,以及你是否真的需要用 flutter 来完成这项工作。我的回答是肯定的哈哈
如果您 运行 Spring 引导服务器,请将“@CrossOrigin”添加到您的控制器或您的服务方法。
@CrossOrigin
@PostMapping(path="/upload")
public @ResponseBody ResponseEntity<Void> upload(@RequestBody Object object) {
// ...
}
我知道这个问题明确要求仅“使用 dart 代码”的解决方案,但我无法使用 dart 代码修复异常(例如通过更改 header)。
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'
更新
我推荐使用。他的封装使得修改Flutter源码非常方便
MacOS 和 Android Studio 的替代解决方案(不修改 Flutter 源)
我们使用与 Osman Tuzcu 类似的方法。我们没有修改 Flutter 源代码,而是在 shell 脚本中添加了 --disable-web-security
参数,并且只转发了 Flutter 设置的所有其他参数。它可能看起来过于复杂,但只需一分钟,无需为每个 Flutter 版本重复。
1。 运行 这个在你的终端里
echo '#!/bin/zsh
# See also
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 中的 无效缓存/重启 强制加载更改。
备注
该脚本还添加了 --test-type
标志来抑制有关已禁用安全功能的丑陋警告。请注意,此选项也可能会抑制其他错误消息!
CHROME_EXECUTABLE
仅采用可执行文件的路径,无法在那里设置参数。
在不捕获退出信号并终止进程组的情况下,当您在 Android Studio 中点击 停止按钮 时,Google Chrome 实例不会被终止。
使用 Osman Tuzcu's answer, I created flutter_cors 可以简化流程。
run/compile 您的 Flutter 网络项目使用 web-renderer。这应该可以解决本地和远程问题:
flutter run -d chrome --web-renderer html
flutter build web --web-renderer html
https://docs.flutter.dev/development/platform-integration/web-images
flutter run -d chrome --web-renderer html
flutter build web --web-renderer html
此官方解决方案仅适用于 Chrome (Source)。但我每次都必须先运行。
flutter run -d chrome --web-renderer html
并且禁用网络安全也有效 ()。但是浏览器会显示一个警告横幅。
但如果您运行使用的浏览器不同于Chrome(例如Edge)并且您希望保留'web security'启用。
您可以在 VS Code 的设置中更改默认 Web 渲染器
File ==> Preferences ==> Settings ==> Enter 'Flutter Web' in the Search Bar ==> Set the default web renderer to html
我认为按照建议禁用网络安全将使您暂时跳过当前错误,但是当您在其他设备上进行生产或测试时,问题将仍然存在,因为它只是一种解决方法,正确的解决方案来自服务器端允许来自请求域的 CORS 并允许所需的方法和凭据(如果需要)。
禁用网络安全的方法在开发中效果很好,但在生产中可能不太好。在生产 dart 代码中对我有用的一种方法涉及通过保持 Web 请求简单来完全避免 pre-flight CORS 检查。在我的例子中,这意味着将请求 header 更改为包含:
'Content-Type': 'text/plain'
即使我实际上发送的是 json,但将其设置为 text/plain 可避免 pre-flight CORS 检查。我调用的 lambda 函数不支持 pre-flight OPTIONS 请求。
这里有一些关于 keep a request simple 和避免 pre-flight 请求
的其他方法的信息
CORS 错误似乎是网络领域的 well-known 问题。但是我第一次尝试 flutter web 时遇到了严重错误。
下面的代码在 运行 在 iOS 设备上时在应用程序版本中运行良好,但是当我在 Chrome 上测试相同的代码并从 beta 通道进行网络调试时,它遇到 CORS 错误。
其他 Whosebug 答案解释了如何解决他们项目的服务器端文件的 CORS 问题。但我完全不知道什么是服务器,也不知道如何处理他们的回答。来自 Chrome 控制台的错误消息低于
[从源 'http://localhost:52700' 访问位于 'https://kapi.kakao.com/v1/payment/ready' 的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' header 出现在请求的资源上。 ]
所以,我想做的是仅使用 DART 代码解决上述 'Access-Control-Allow-Origin header' 问题!下面的代码是我试图用 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);
},
尽管我实际上有大多数其他答案推荐的 header "Access-Control-Allow-Origin": "*"
,但 Chrome 控制台打印了相同的错误消息。奇怪的是,相同的代码在 mobileApp 版本中发出了成功的请求。所以我认为这只是 flutter WEB 版本的问题。
希望有人能解决并建议 only-dart 代码来解决我 main.dart 中的问题!!感谢您阅读 [:
我认为你这样做的方式可能不对。 cors headers 应该添加到 HTTP 响应 header 中,而你显然在 reuqest header 中添加了它们。
有关详细信息,请查看文档 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#what_requests_use_cors
1- 转到 flutter\bin\cache
并删除名为:flutter_tools.stamp
2- 转到 flutter\packages\flutter_tools\lib\src\web
并打开文件 chrome.dart
。
3- 查找'--disable-extensions'
4- 添加 '--disable-web-security'
真正需要像 node js 或 django 这样的服务器端引擎来使用带有一堆外部 apis 的 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 开发人员,以稳定地学习节点 js 等服务器端引擎。值得一试。
如果您一直到我的自我回答的这一行,这里有一个使用节点 js 的 flutter web 的简单指南。 Flutter web 处于稳定状态,但所有必要的基础设施还没有为像我这样的新手准备好。所以当你第一次涉足 web 领域时要小心,并希望你重新检查所有条件和要求,以确定你是否真的需要你的 flutter 应用程序的 web 版本,以及你是否真的需要用 flutter 来完成这项工作。我的回答是肯定的哈哈
如果您 运行 Spring 引导服务器,请将“@CrossOrigin”添加到您的控制器或您的服务方法。
@CrossOrigin
@PostMapping(path="/upload")
public @ResponseBody ResponseEntity<Void> upload(@RequestBody Object object) {
// ...
}
我知道这个问题明确要求仅“使用 dart 代码”的解决方案,但我无法使用 dart 代码修复异常(例如通过更改 header)。
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'
更新
我推荐使用
MacOS 和 Android Studio 的替代解决方案(不修改 Flutter 源)
我们使用与 Osman Tuzcu 类似的方法。我们没有修改 Flutter 源代码,而是在 shell 脚本中添加了 --disable-web-security
参数,并且只转发了 Flutter 设置的所有其他参数。它可能看起来过于复杂,但只需一分钟,无需为每个 Flutter 版本重复。
1。 运行 这个在你的终端里
echo '#!/bin/zsh
# See also
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 中的 无效缓存/重启 强制加载更改。
备注
该脚本还添加了 --test-type
标志来抑制有关已禁用安全功能的丑陋警告。请注意,此选项也可能会抑制其他错误消息!
CHROME_EXECUTABLE
仅采用可执行文件的路径,无法在那里设置参数。
在不捕获退出信号并终止进程组的情况下,当您在 Android Studio 中点击 停止按钮 时,Google Chrome 实例不会被终止。
使用 Osman Tuzcu's answer, I created flutter_cors 可以简化流程。
run/compile 您的 Flutter 网络项目使用 web-renderer。这应该可以解决本地和远程问题:
flutter run -d chrome --web-renderer html
flutter build web --web-renderer html
https://docs.flutter.dev/development/platform-integration/web-images
flutter run -d chrome --web-renderer html
flutter build web --web-renderer html
此官方解决方案仅适用于 Chrome (Source)。但我每次都必须先运行。
flutter run -d chrome --web-renderer html
并且禁用网络安全也有效 (
但如果您运行使用的浏览器不同于Chrome(例如Edge)并且您希望保留'web security'启用。 您可以在 VS Code 的设置中更改默认 Web 渲染器
File ==> Preferences ==> Settings ==> Enter 'Flutter Web' in the Search Bar ==> Set the default web renderer to html
我认为按照建议禁用网络安全将使您暂时跳过当前错误,但是当您在其他设备上进行生产或测试时,问题将仍然存在,因为它只是一种解决方法,正确的解决方案来自服务器端允许来自请求域的 CORS 并允许所需的方法和凭据(如果需要)。
禁用网络安全的方法在开发中效果很好,但在生产中可能不太好。在生产 dart 代码中对我有用的一种方法涉及通过保持 Web 请求简单来完全避免 pre-flight CORS 检查。在我的例子中,这意味着将请求 header 更改为包含:
'Content-Type': 'text/plain'
即使我实际上发送的是 json,但将其设置为 text/plain 可避免 pre-flight CORS 检查。我调用的 lambda 函数不支持 pre-flight OPTIONS 请求。
这里有一些关于 keep a request simple 和避免 pre-flight 请求
的其他方法的信息