我有大量 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/