如何在颤动的 Web http 请求中添加标头?

Posted

技术标签:

【中文标题】如何在颤动的 Web http 请求中添加标头?【英文标题】:How to add header to flutter web http request? 【发布时间】:2021-09-06 13:00:36 【问题描述】:

带有 http: ^0.13.3 包的 Flutter Web 应用程序 http 请求。下面是我从 api Server 检索数据的代码。

var data = await http.get(Uri.http(ServerRoot, "api/conversation/1"),);

但添加身份验证标头会给我以下错误。同样的代码在 androidios 项目上运行良好,但是 web 项目给了我错误。

 var data = await http.get(Uri.http(ServerRoot, "api/conversation/1"),
                headers: 
      HttpHeaders.authorizationHeader: "bearer $token"
    );

我无法检索数据,它给了我以下错误

Error: XMLHttpRequest error.
    dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 909:28                get current
packages/http/src/browser_client.dart 71:22                                       <fn>
dart-sdk/lib/async/zone.dart 1613:54                                              runUnary
dart-sdk/lib/async/future_impl.dart 155:18                                        handleValue
dart-sdk/lib/async/future_impl.dart 707:44                                        handleValueCallback
dart-sdk/lib/async/future_impl.dart 736:13                                        _propagateToListeners
dart-sdk/lib/async/future_impl.dart 533:7                                         [_complete]
dart-sdk/lib/async/stream_pipe.dart 61:11                                         _cancelAndValue
dart-sdk/lib/async/stream.dart 1219:7                                             <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 324:14  _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 329:39  dcall
dart-sdk/lib/html/dart2js/html_dart2js.dart 37307:58                              <fn>


    at Object.createErrorWithStack (http://localhost:49464/dart_sdk.js:5054:12)
    at Object._rethrow (http://localhost:49464/dart_sdk.js:37670:16)
    at async._AsyncCallbackEntry.new.callback (http://localhost:49464/dart_sdk.js:37666:13)
    at Object._microtaskLoop (http://localhost:49464/dart_sdk.js:37526:13)
    at _startMicrotaskLoop (http://localhost:49464/dart_sdk.js:37532:13)
    at http://localhost:49464/dart_sdk.js:33303:9

google chrome 控制台消息如下

【问题讨论】:

【参考方案1】:

这个一般错误是因为浏览器没有提供 http 库可以显示的正确错误消息:

https://github.com/dart-lang/http/blob/e89b190936d53d0e36148436283e28ba1091b35a/lib/src/browser_client.dart#L66-L72

  // Unfortunately, the underlying XMLHttpRequest API doesn't expose any
  // specific information about the error itself.

要对此进行调试,您应该使用浏览器开发人员工具中的“网络”选项卡来检查发送的请求,以检查它是否包含您预期的标头,如果是,则服务器会响应以查看失败的原因。

如果问题是 CORS(并且 CORS 错误不仅仅是因为服务器返回了错误响应),那么您需要让后端包含相关的 CORS 标头。

如果是第三方服务,您应该向他们询问。如果它是您自己的服务,那么您需要添加一个 Access-Control-Allow-Origin 标头,其中包含应该允许使用您的服务的 Origin(不包括 *.. 您可能需要临时使用 localhost 源进行测试,但是请在部署时为您的站点使用正确的域,以便其他站点无法调用您的 API)。

【讨论】:

我已经用谷歌浏览器开发者控制台错误更新了我的问题,请看一下 请检查网络选项卡并检查来自服务器的响应。我怀疑这是一个错误响应(如果您的标头不正确,可能是由于身份验证失败)。该错误表明 CORS 错误,尽管这可能只是因为 错误响应 不包含 CORS 标头,而不是实际上是 CORS 问题。 我已经禁用了网络安全及其现在的工作,但我认为这不是一个好习惯,我不能要求最终用户禁用他们的网络安全来使用我的应用程序 我同意 - 您应该通过检查“网络”选项卡来找出实际问题。如果问题确实是 CORS,那么您需要后端提供适当的 CORS 标头以允许您的应用程序使用它。从您的帖子中不清楚后端是您正在构建的东西还是第三方服务。 我在答案的底部添加了一些额外的注释。【参考方案2】:

我发现这是谷歌浏览器的错误,我必须在终端上运行以下命令才能按照建议here打开带有禁用安全性的谷歌浏览器

# MacOS
open -na Google\ Chrome --args --user-data-dir=/tmp/temporary-chrome-profile-dir --disable-web-security --disable-site-isolation-trials

这样做后我的 chrome 显示警告 这样做之后,我在 Flutter Web 上运行了相同的代码。我不知道禁用网络安全是否更好。

一旦部署,我不能要求用户禁用网络安全。

【讨论】:

请不要这样做。查看我的答案的更新。

以上是关于如何在颤动的 Web http 请求中添加标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何为Web请求指定标头

如何在反应 js 应用程序的响应中添加 http 标头

如何在传入的http请求标头中添加授权令牌[关闭]

如何将承载令牌添加到 HTTP 请求的标头?

如何在注入 JAX-RS Web 服务的 CDI bean 中获取 HTTP 请求标头?

如何向每个标头添加 json Web 令牌?