【问题标题】:JSONP callback doesn't execute when running at localhost在本地主机上运行时不执行 JSONP 回调
【发布时间】:2010-11-16 02:50:30
【问题描述】:

这很奇怪,我想知道是否有人可以解释为什么会这样。

基本上,我一直在努力测试 JSONP,以便实现其他网站可以使用的 JSON Web 服务。我正在本地主机上进行开发——特别是 Visual Studio 2008 和 Visual Studio 2008 的内置 Web 服务器。

因此,作为一个带有 jQ​​uery 的 JSONP 测试运行,我实现了以下内容:

$().ready(function() {
  debugger;
  try {
    $.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) {
        alert(data.abc);
    });
  } catch (err) {
    alert(err);
  }
});

在服务器上..

<%= Request["callback"] %>({abc : 'def'})

所以最终发生的事情是我在服务器上设置了一个断点,并且我在第一个“调试器”上都获得了断点;客户端脚本以及服务器上的语句。 JSONP URL 确实在页面加载后被调用。效果很好。

我遇到的问题是回调永远不会执行。我在 IE8 和 Firefox 3.5 中都对此进行了测试。没有人会调用回调。也从未达到 catch(err)。什么都没发生!

我已经坚持了一周,甚至在 Telnet 中在指定端口上使用手动键入的 HTTP 请求进行了测试,以确保服务器正在返回格式...

callbackfn({abc : 'def'})

.. 确实如此。

然后我突然明白了,如果我用全球化器('.')将主机名从 localhost 更改为 localhost,例如 http://localhost.:41559/ 而不是 http://localhost:41559/(是的,在任何主机名中添加一个点是合法的,它对于 DNS 就像 global:: 对于 C# 命名空间一样)。然后它起作用了!当我添加一个点时,Internet Explorer 和 Firefox 3.5 终于向我显示了一条警告消息。

所以这让我想知道,这里发生了什么?为什么后期脚本标记生成可以使用 Internet 主机名而不是普通 localhost?或者这是正确的问题?

显然,这是出于安全原因而实施的,但他们试图保护什么?而且,通过让它与点一起工作,我是否只是暴露了这个安全功能中的一个安全漏洞?

顺便说一句,我的 hosts 文件虽然针对其他主机进行了更改,但与 localhost 并没有什么特别之处;默认的 127.0.0.1 / ::1 仍然存在,下面没有覆盖。

跟进:我通过添加以下内容来解决本地开发问题:

127.0.0.1   local.mysite.com

.. 到我的 hosts 文件中,然后将以下代码添加到我的 global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.Headers["Host"].Split(':')[0] == "localhost")
    {
        Response.Redirect(
            Request.Url.Scheme
            + "://"
            + "local.mysite.com"
            + ":" + Request.Url.Port.ToString()
            + Request.Url.PathAndQuery
            , true);
    }
}

【问题讨论】:

  • 我建议使用 firebug 之类的工具,看看是否正在为 JSONP 内容执行“脚本”请求,并实际查看返回的数据。
  • 数据有效。如上所述,解决方法是远离 localhost(否则脚本和数据保持不变)并“修复”它,但不能完全解释发生了什么。
  • 是的,这就是为什么我建议记录未修复版本的事件。
  • 我做到了,卢卡。感谢您的建议。
  • 我想知道这是否相关:bugzilla.mozilla.org/show_bug.cgi?id=560594

标签: javascript localhost jsonp xss


【解决方案1】:

我将在那里抛出一个答案;经过一番思考,我得出了自己的结论。

这可能是一项安全功能,旨在阻止 Internet 网站调用运行在客户端计算机上的 JSONP 服务。

一个网站可以只浏览一个端口列表,并在不同的端口和路径上不断调用 localhost。 “Localhost”是少数 DNS 主机名之一,其含义取决于查询的时间和地点,从而使潜在目标易受攻击。是的,将点 (.) 附加到 'localhost' ('localhost.') 会产生一个可行的解决方法,这确实暴露了一个安全漏洞,但确实为开发目的提供了一个 [暂定的] 解决方法。

更好的方法是将环回 IP 映射到 hosts 文件中的新主机名条目,以便它在本地工作,不容易被浏览器更新“修复”,并且除了在其他任何地方都不能工作开发工作站。

【讨论】:

    【解决方案2】:

    我遇到了类似的问题。我尝试过的大多数解决方案都适用于 IE (7),但我很难让 Firefox (3.5.2) 发挥作用。

    我已经安装了 HttpFox 以查看我的服务器响应在客户端上是如何被解释的,并且我得到了 NS_ERROR_DOM_BAD_URI。不过,我的情况与您的情况有些不同,因为我试图调用 JSONP 调用返回到托管页面来自的同一站点,然后此调用响应 302 重定向到另一个站点。 (我使用重定向作为一种方便的方式从两个域中获取 cookie 返回到浏览器。)

    我正在使用 jQuery,我最初尝试通过 $.ajax() 进行标准 AJAX 调用。我认为由于初始请求是针对与托管页面相同的站点,Firefox 只会跟随对另一个域的 302 响应。但不,它似乎违反了 XSS 防御。 (请注意,与Returning redirect as response to XHR request 所暗示的相反,jQuery 确实遵循标准 dataType="json" 调用的 302 重定向:重定向到同一个域工作正常;重定向到另一个域会在浏览器中生成 NS_ERROR_DOM_BAD_URI。)除此之外,我不明白为什么不能只遵循同域 302 重定向到其他域 - 毕竟,发出重定向的是托管页面的域,那么为什么不能信任它呢?如果您担心脚本注入攻击,那么 JSONP 路由无论如何都可能被滥用...

    jQuery 的 $.getJSON() 带有 ?callback=?后缀在 Firefox 中也会失败,并出现同样的错误。就像使用 $.getScript() 来滚动我自己的 JSONP

    似乎有效的是,在 HTML 中有一个预先存在的 然后使用 $("jsonp").attr(" src", url + "?callback=myCallback") 来调用 JSONP 调用。如果我这样做了,那么跨域 302 重定向将被执行,并且我将 JSON 响应传递给 myCallback(我已与 标记同时定义)。

    而且,是的,我正在使用 Cassini 和 localhost:port URL 来开发所有这些。 Cassini 不会响应非本地主机的 URL,所以我不能轻易尝试 local.mysite.com 看看这是否对我上面尝试的解决方案有任何影响。但是,在 localhost 末尾添加一个点似乎解决了我所有的问题!

    现在我可以使用 localhost__.__:port 而不是 localhost: 回到标准的 $.ajax({ ... dataType:"jsonp" ... }) 调用端口,一切都很好。我发现修改页面 HTML does 中预先存在的脚本标记的 src 属性允许调用普通的本地主机 URL 很有趣 - 我想按照您的思考过程,这可能是另一个安全漏洞.

    【讨论】:

      猜你喜欢
      • 2016-05-20
      • 1970-01-01
      • 2020-11-04
      • 2017-09-06
      • 2019-02-12
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多