json - 通过 JSONP 在 CDN 上的静态 JSON 文件

标签 json jsonp cdn

我有大量 JSON 格式的静态/很少变化的数据。为了提高我的 ASP.NET MVC 应用程序性能,我想将它们移动到 CDN(Amazon Cloud Front)。

但是,当我这样做时,跨域策略启动并且 jQuery 进行 HTTP OPTIONS 方法调用而不是 HTTP GET 并且 Amazon 以“403 Forbidden”响应拒绝请求。

JSONP 可能是解决此问题的一种方法,但由于文件是静态的并且在 CDN 上,因此无法将 JSON 包装在自定义函数中。但是我可以用已知的函数名重新创建它们。例如:

{"LineDetails":{"LineNo":"3109","DbId":9 ....}}

我可以做类似的事情:
JsonWrapping({"LineDetails":{"LineNo":"3109","DbId":9 ....}});

所有文件的“JsonWrapping”函数名称都相同。

jQuery 是否可以通过 JSONP 下载 JSON 数据,如果它包装在与上面所示相同的函数名称中?我对 jQuery JSONP 的解读是 jQuery 为 JSONP 请求创建了一些自定义的一次性使用函数名称。这可以被覆盖吗?

谢谢你的帮助。

最佳答案

jQuery JSONP 的最佳实践

$.getJSON 的文档中和 $.ajax ,jsonp 部分指出,您可以使用 jsonpCallback 显式设置回调函数名称配置属性。所以如果你想要JsonWrapping(...)要成为 jquery 在 jsonp 响应中所期望的函数,您可以像这样将事情联系起来:

$.ajax({
    url: 'http://blah.com/blah.json'​​​​​​​​​​​​​​​​​​​​​​​​,
    dataType: 'jsonp',
    cache: true,
    jsonpCallback: 'JsonWrapping'
})
.done(function(r) {
    status.text('It worked.');
})
.fail(function (a, b, c) {
    status.text('It failed.');
});​​​​​​​​​​​​​​​​​​​​​​​​

在上面的示例中,jsonp 响应中的预期回调函数现在是 JsonWrapping() ,jQuery 会为你发出,通过调用 .done() 来响应。上面,然后自己清理——比硬编码要干净得多JsonWrapping进入页面。

硬编码和命名建议的危险

需要考虑的重要一点是,如果您计划在单个页面上进行许多 jsonp 调用,并且您的 jsonp 包装函数在 jsonp 文件中是硬编码的,那么您至少应该通过文件名之类的东西来改变您的包装函数。否则你会产生一个异步问题。例如假设你有这个代码:
function jsonp(url) {
    return $.ajax({
        url: url,
        dataType: 'jsonp'
        cache: true,
        jsonpCallback: 'JsonWrapping'
    });
}

jsonp('http://cdn.mine/one.jsonp')
.done(...);

jsonp('http://cdn.mine/two.jsonp')
.done(...);

其中一个 jsonp 调用将在另一个之前完成 - 不可能知道哪个 - 并且 jQuery 处于不可能知道哪个 .done() 的不可能的情况下。呼吁作出何种回应。结果,您将在正确调用它们的地方获得一些页面加载,以及在数据交叉的地方加载一些页面。解决方案是改变文件名之类的内容,例如:
function jsonp(url, wrapper) {
    return $.ajax({
        url: url,
        dataType: 'jsonp'
        cache: true,
        jsonpCallback: wrapper
    });
}

jsonp('http://cdn.mine/one.jsonp', 'one')
.done(...);

jsonp('http://cdn.mine/two.jsonp', 'two')
.done(...);

所以来自 two.jsonp 的响应需要如下所示:
two({...json object here...})

这个怎么运作

此答案开头的调用将使 jQuery 通过 GET 请求 URL,如下所示:
http://blah.com/blah.json?callback=JsonWrapping

并期望这是响应:
JsonWrapping({...object here...})

我包括cache: true上面,因为这是在 CDN 上,因此,大概不会经常更改。如果您离开 cache: true出来,jQuery 插入第二个查询字符串参数,用于缓存清除,例如:
http://blah.com/blah.json?callback=JsonWrapping&_=1365175172440

这可能会破坏 CDN 的意义。第二个查询字符串参数的目标是确保数据不会从浏览器缓存中加载,并且当它到达服务器(在本例中为 CDN)时,查询字符串是唯一的,这意味着它也会破坏其缓存。

在您使用 CDN 的场景之外,在某些情况下需要 jQuery 的默认功能:例如,当您想在不违反同源策略的情况下模拟跨域的 POST 功能时,具有此缓存破坏功能的 jsonp 可以帮您完成。

如果您正在与之交谈的服务器期望查询字符串中的“回调”以外的内容用于在响应中指定回调函数的名称,您可以使用 jsonp配置属性 - 例如 jsonp: 'myname'会让你:
http://blah.com/blah.json?myname=JsonWrapping

关于json - 通过 JSONP 在 CDN 上的静态 JSON 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3296510/

相关文章:

json - stream2es线程错误中的异常

java - Jersey JSON 响应作为 HttpUrlConnector 而不是 JSON

javascript - ajaxcontroltoolkit 的 Ajax CDN 支持

javascript - 耶普诺普后备

css - 控制 css 加载顺序

javascript - 当用户代理是curl时,从浏览器返回不同的响应

ios - RestKit - 嵌套结构失败

javascript - 无法选择通过 select2 中的 jsonp 填充的项目

javascript - AJAX跨域调用

python - 错误的 JSON - 键未被引用