【问题标题】:Replace server JSON response in Chrome在 Chrome 中替换服务器 JSON 响应
【发布时间】:2013-02-11 11:10:06
【问题描述】:

我遇到了一些以 AJAX 方式向服务器查询 JSON 数据的基于 Web 的工具的问题。它无法正常工作 - 返回的结果通常不是我想要的,我需要等待很多时间让服务器处理请求。

事实上,我总是希望返回相同的数据(准确地说是几个人),所以我想到了伪造服务器响应。我尝试了几种方法来实现这一点,但没有成功。

我尝试使用 Chrome 的 WebRequest 功能 - 我准备了一个扩展并将请求重定向到我的 JSON 编码的数据 URL。它有效,但只有当我在 Chrome 的地址字段中手动输入地址时。当 Web 应用程序尝试访问该地址时,重定向静默失败。我立即想到了 Access Origin 限制,并迅速设置了一个发送 Access-Control-Allow-Origin 标头的 Web 服务器。

不幸的是,这也不起作用。当我手动输入地址时,正在查询服务器并返回正确的 JSON,但在应用程序中请求......默默地失败了。看起来 Chrome 完全忽略了可能的 Access-Control-Allow-Origin 标头,因为它甚至没有查询服务器。 Chrome 很可能只分析 URL,因为当我将有问题的请求重定向到应用程序域中的随机 URL 时它起作用了。

我还尝试使用相同的方法伪造应用程序的整个 JavaScript 文件 - 该文件静态链接到文档(例如,它通过标准脚本标签包含)。我失败得很惨——重定向只是默默地失败了,就像我第一次尝试失败一样。

我的问题的一个常见解决方案是使用某种代理来更改服务器输出,但我不能这样做 - 我不想等待几分钟让服务器处理请求。顺便说一句,该应用程序只能通过 HTTPS 访问。

有没有其他方法可以使用我的硬编码 JSON 来提供应用程序?或者我错过了什么?

编辑 插件代码,基于“catblock”示例:

chrome.webRequest.onBeforeRequest.addListener(
function(info) {
  console.log("AJAX call intercepted: " + info.url)
  return {redirectUrl: 'data:application/json,"test"'};
},
// filters
{
  urls: [
  "*://address.to.the.js.file.requested"
]
}, ['blocking']);

清单文件,我只将域添加到权限部分:

{
"name": "CatBlock",
"version": "1.0",
"description": "I can't has cheezburger!",
"permissions": ["webRequest", "webRequestBlocking", 
              "*://some.domain.com/*"],
"background": {
  "scripts": ["background.js"]
},

"manifest_version": 2
}

编辑 2: 以下是 Chrome 开发者控制台网络面板的屏幕截图,显示请求被静默取消:

【问题讨论】:

  • “我尝试使用 Chrome 的 WebRequest 功能” - 您是否在过滤器中添加了“xmlhttprequest”?显示您当前据称已损坏的扩展程序。
  • @RobW:我添加了代码,抱歉耽搁了 - 我无法更快地回答您的请求。
  • 您的请求因同源策略而失败(在 Chrome 中,data: 被视为不同的源)。您必须访问 http(s) 资源并将 CORS 标头附加到响应中。
  • @RobW:我想出了这个解决方案,正如我在问题中提到的那样 - 它没有用。当应用程序请求 JSON 时,Chrome 甚至没有向我的 HTTP 服务器发出请求。需要明确的是 - 当我手动输入地址时,一切都很好。我认为这与同源策略有关,但 Chrome 内部假定它应该取消请求,甚至不查看返回的标头。
  • 当您将redirectUrl 与来自不同来源的资源一起使用时,请求将被取消。您是否添加了CORS 响应标头,正如我在之前的评论中提到的那样? (要进行快速测试,请附加Access-Control-Allow-Origin: *)。

标签: google-chrome google-chrome-extension


【解决方案1】:

有几种方法可以做到这一点。

最简单的方法是使用Fiddler 如果你懂俄语,或者你的浏览器有不错的翻译功能,你可以阅读这个article——据我所知,在你的情况下你需要第二部分——关于自动回复。 或者下面有几个英文手册的链接。

这个截图就是答案

关于 chrome 中的 Access-Control-Allow-Origin - 我的 extension 也非常简单(只需添加到响应标题“Access-Control-Allow-Origin:*”)并允许您在开发时避免此错误特征。你可以用 Fiddler 做同样的事情 同样在 chrome 中,您可以使用开发人员密钥“chrome --disable-web-security”运行 Chrome 它也消除了“Access-Control-Allow-Origin”的错误

【讨论】:

  • 问题与Access-Control-Allow-Origin没有直接关系。它是一种内置机制,它拒绝重定向,甚至不尝试检查标头。即使禁用网络安全也不会禁用它。 Fiddler 会完成这项工作,但我想要一个基于 Chrome 扩展的解决方案。由于该应用程序仅通过 HTTPS 提供服务,因此我需要设置 Fiddler 来进行 MiM 攻击,并且由于我想每天都使用它,而不仅仅是用于测试,所以我想避免这样做。
【解决方案2】:

如果我理解正确, 可以控制生成 JSON 响应的服务器。 如果是这种情况,那么必须有可能 - 没有任何 Chrome 扩展 - 让 AJAX (XMLHTTPRequest) 请求和响应使用正确的 CORS 标头。

根据我的经验,失败的跨域 XHR 请求仅似乎在 Chrome 中“静默”失败,但如果您仔细查看控制台,您会看到一条错误消息 类似于

XMLHttpRequest 无法加载 http://example.com/yourJSONfile.json。 Access-Control-Allow-Origin 不允许来源http://your-app-domain.com:80

此消息有时可能会产生误导,因为如果 任何事情 CORS 相关出现错误(即使 Access-Control-Allow-Origin 设置正确),它也会显示出来。 此外,在网络选项卡上,您将看到 XHR 请求和响应标头。

现在让我们谈谈 CORS 标头。我必须查看您请求的 AJAX 选项或 HTTP 请求标头才能准确说明您需要哪些 CORS 标头,但据我现在所知,“Access-Control-Allow-Origin: *”可能不足以满足您的要求成功: 根据您的请求标头(我目前不知道,因此以下只是示例),您可能需要额外的 CORS 标头,例如:

"Access-Control-Allow-Methods": "OPTIONS, GET, POST"

“Access-Control-Allow-Headers”:“内容类型,接受,来源”

此外,出于调试目的,启用:

"Access-Control-Expose-Headers": "Access-Control-Allow-Origin"

这样您就可以在网络选项卡上看到与 CORS 相关的响应标头。

【讨论】:

  • 好吧,我不受原始服务器的控制,但我受其他可以发送更改数据的服务器的控制。问题是,请求似乎不只是默默地失败。它真的默默地失败了。控制台中没有错误 - 只有一个误导性警告 The page at "https://the.app.com displayed insecure content from http://.../my.json",但 Chrome 甚至没有向托管 my.json 文件的服务器发出请求。我用开发控制台的屏幕截图更新了我的问题。
  • 你控制的服务器能否从原服务器接收到正确的数据?
  • 因此,您可以在服务器上设置代理并缓存来自远程服务器的响应。这将大大减少您现在向远程服务器发送请求时的延迟。您的脚本会将请求发送到您的服务器,如果缓存存在则立即返回到脚本,如果不存在则将请求转发到远程服务器,并且在响应到达时将其缓存并转发回您的脚本。跨度>
  • @user1234567,您提到最终产品是基于 Web 的工具。这导致我建议您放弃 Chrome 的 webrequest 扩展,而是专注于对由基于 Web 的工具中的 javascript 代码触发的 XHR 进行故障排除。然后,当您像我在回答中建议的那样检查标头时,您将有很好的机会正确设置 CORS 响应标头。故障排除中的一个重要步骤是通过指定“Access-Control-Expose-Headers”来公开响应标头:“Access-Control-Allow-Origin”
  • @bancer:是的,但这仍然存在问题。 marty - 我完全理解你的观点 - 但你假设 Chrome 在应用程序请求 JSON 时将请求发送到我的服务器。我的问题是 Chrome 总共向服务器发送了 0(零)个字节。我已经使用wireshark 验证了这条语句,另外还通过在监听模式下使用netcat 作为假服务器来验证。
猜你喜欢
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多