Chrome 中的跨域问题可能是奇怪的 Dart HttpRequest 行为的 b/c
Posted
技术标签:
【中文标题】Chrome 中的跨域问题可能是奇怪的 Dart HttpRequest 行为的 b/c【英文标题】:Cross-Domain issue in Chrome possibly b/c of strange Dart HttpRequest behavior 【发布时间】:2015-07-02 11:40:44 【问题描述】:我知道伙计们,有很多关于 Amazon S3
Buckets 和 CORS
的问题。但是,请让我添加我的。
所以我正在Dart
中编写一个应用程序,并且我正在对托管在 S3 上的资源执行 ajax 请求。我最初想获取资源的前 100 个字节,这就是为什么我想出了下面这段漂亮的代码:
HttpRequest req = new HttpRequest();
req.open('GET', item.get('upload').get('url'));
req.setRequestHeader('Range', 'bytes=0-99');
req.onReadyStateChange.where((e) => req.readyState == HttpRequest.DONE).first.then((e)
print(req.responseText);
);
req.send();
正如您可能从这个问题的标题中猜到的那样,这段代码不起作用,我得到了一个
请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://localhost:8080' 因此不允许访问。
这对我来说似乎很奇怪,因为我设置了一个 CORS
应该可以防止这个问题......
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedHeader>*</AllowedHeader>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
</CORSRule>
</CORSConfiguration>
无论出于何种原因,这显然行不通。我在 Firefox 中加载了应用程序,瞧,它正在工作。似乎CORS
确实有效,问题是因为Chrome
或Dart
。
我摆弄了一下,由于某些原因,请原谅,这里已经很晚了,我想出了这个:
HttpRequest req = new HttpRequest();
req.open('GET', item.get('upload').get('url'));
req.setRequestHeader('Range', '0-99');
req.onReadyStateChange.where((e) => req.readyState == HttpRequest.DONE).first.then((e)
print(req.responseText);
);
req.send();
是的,我刚刚从之前的代码中删除了bytes=
。你猜怎么着,突然我的 ajax 请求运行并打印出全文。呜?!我可以添加一个损坏的Range Header
并解决这个安全问题?嗯,这正是刚刚发生的事情。当然,我得到的不仅仅是前 100 个字节,但至少我得到了一些东西。由于我没有解释为什么损坏的Range
标头使请求工作,我用其他一些随机字符串替换了Range
标头,但它们都不起作用。
我知道,您的想法可能刚刚被打破 - 我的也是!因此,我想总结一下我们刚刚发现的内容。
由于安全问题,在 Chrome 中使用 Dart 发出跨域 ajax 请求不起作用,但 设置的 CORS 似乎至少适用于 Firefox。 可以通过添加损坏的Range
请求标头来“利用”Chrome 的安全问题,但是
没有其他标题具有相同的效果。
真的吗?我的意思是,我不知道这里发生了什么。 任何人都可以至少向我解释一些事情吗? - 如果有人有想法或解决方案来解决我无法在 Chrome 中获取前 100 个字节的问题,我将在余生中感激不尽。
提前谢谢你!
【问题讨论】:
听起来很奇怪。 CORS 不是编程语言问题,而是浏览器/服务器问题。你试过 Chrome 和 Dartium 吗?有什么区别吗?你能在浏览器 DevTools 中调查响应是什么样的吗? 响应本身是空的。这些是响应标头:pastebin.com/euzrG8uN @GünterZöchbauer 我也刚刚发现,当我将请求移动到 main_app.dart 以使其成为执行的第一条语句时,一切正常。 两者之间会发生什么(app-start 到请求的位置?)。通常从哪里发出请求? 该应用程序由 70 多个自行编写的 Polymer 元素组成,并使用了大量的 Core 和 Paper 元素。它非常庞大,并且在开始和发出请求的点之间发生了很多事情。该请求通常由自定义 Polymer 元素中的attached()
回调发出。然而,main_app 也是一个自定义的 Polymer 元素。因此,我认为问题与聚合物无关。目前,我完全不知道如何继续调试这个问题。
【参考方案1】:
我终于设法修复了这个错误。
不,它既不是 Chrome 也不是 Dart 错误。它与一些缓存有关。解决方案是简单的脏字符串查询破解:
HttpRequest req = new HttpRequest();
req.open('GET', '$item.get('upload').get('url')?t=$new Random().nextInt(99999)');
req.setRequestHeader('Range', '0-99');
req.onReadyStateChange.where((e) => req.readyState == HttpRequest.DONE).first.then((e)
print(req.responseText);
);
req.send();
在查询中添加一个随机数会导致缓存,我不知道是亚马逊还是Chrome的缓存,做正确的事情。
【讨论】:
以上是关于Chrome 中的跨域问题可能是奇怪的 Dart HttpRequest 行为的 b/c的主要内容,如果未能解决你的问题,请参考以下文章
来自 Google Chrome 中的用户脚本的跨域 XHR