我有大量的JSON格式的静态/很少变化的数据.为了提高我的ASP.NET MVC应用程序性能,我想将它们转移到CDN(Amazon Cloud Front).
但是,当我这样做时,跨域策略启动并且jQuery进行HTTP OPTIONS方法调用而不是HTTP GET,并且亚马逊拒绝了"403 Forbidden"响应的请求.
JSONP可能是解决此问题的方法,但由于文件是静态的并且在CDN上,因此无法将JSON包装在自定义函数中.但是我可以用已知的函数名重新创建它们.例如:
{"LineDetails":{"LineNo":"3109","DbId":9 ....}}
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
JsonWrapping({"LineDetails":{"LineNo":"3109","DbId":9 ....}});
Run Code Online (Sandbox Code Playgroud)
所有文件的"JsonWrapping"函数名称都相同.
如果jQuery包含在如上所示的相同函数名中,jQuery是否可以通过JSONP下载JSON数据?我对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.');
});????????????????????????
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,jsonp响应中的预期回调函数现在JsonWrapping()是jQuery将为您发出的,通过调用.done()上面的响应,并在自身之后进行清理 - 比硬编码JsonWrapping到页面更清晰.
需要考虑的一件重要事情是,如果你计划在一个页面上进行许多jsonp调用,并且你的jsonp包装函数在jsonp文件中是硬编码的,那么你应该至少改变你的包装函数,比如filename.否则,您将创建异步问题.例如假设你有这个代码:
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(...);
Run Code Online (Sandbox Code Playgroud)
其中一个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(...);
Run Code Online (Sandbox Code Playgroud)
所以来自two.jsonp的响应需要看起来像:
two({...json object here...})
Run Code Online (Sandbox Code Playgroud)
这个答案开头的调用将使jQuery通过GET请求URL,如下所示:
http://blah.com/blah.json?callback=JsonWrapping
Run Code Online (Sandbox Code Playgroud)
并期待这作为回应:
JsonWrapping({...object here...})
Run Code Online (Sandbox Code Playgroud)
我cache: true上面列出的是因为这是在CDN上,因此,大概不会经常改变.如果cache: true省略,jQuery会插入第二个用于缓存清除的查询字符串参数,例如:
http://blah.com/blah.json?callback=JsonWrapping&_=1365175172440
Run Code Online (Sandbox Code Playgroud)
这可能会破坏CDN的重点.第二个查询字符串参数的目标是确保数据不从浏览器缓存加载,并且当它到达服务器(在这种情况下为CDN)时,查询字符串是唯一的,这意味着它也会破坏其缓存.
在您使用CDN的场景之外,有些情况下需要jQuery的默认功能:例如,当您想要将POST功能模拟到另一个域而不违反Same-Origin策略时,具有此缓存清除功能的jsonp可以为你完成这件事.
如果您正在与之交谈的服务器在查询字符串中需要"回调"之外的其他内容来指定响应中回调函数的名称,则可以使用jsonpconfig属性 - 例如jsonp: 'myname',它会让您:
http://blah.com/blah.json?myname=JsonWrapping
Run Code Online (Sandbox Code Playgroud)
我刚刚发现这在某种程度上是可能的。我是这样解决的:
$(document).ready(function(){
$.getJSON("http://example.com/staticjsonfile.json",function(data){
//callback function isn't here
}
});
function JsonWrapping(data){
//It's really here
alert(data);
}
Run Code Online (Sandbox Code Playgroud)
这并不理想,因为您失去了与触发 Ajax 请求的事件的绑定。所以需要一些黑客技术。然而,它有点完成工作。我非常乐意接受更好的解决方案。
| 归档时间: |
|
| 查看次数: |
5824 次 |
| 最近记录: |