jQuery getJSON 回调不起作用 - 即使使用有效的 JSON - 并且似乎使用的是“OPTION”请求而不是“GET”
Posted
技术标签:
【中文标题】jQuery getJSON 回调不起作用 - 即使使用有效的 JSON - 并且似乎使用的是“OPTION”请求而不是“GET”【英文标题】:jQuery getJSON callback does not work - even with valid JSON - and seems to be using "OPTION" request not "GET" 【发布时间】:2010-11-14 06:47:06 【问题描述】:背景是我有一个配置有 Django 视图的 celery 分布式作业服务器,该视图以 JSON 格式返回正在运行的作业的状态。作业服务器位于 celeryserver.mydomain.com 并且我正在执行 jQuery 的页面是 www.mydomain.com 所以我不应该为此考虑 JSONP,因为没有向不同的域?
查看我的服务器日志,我看到 jQuery 每隔 3 秒执行一次 getJSON
调用(使用 javascript setInterval)。它似乎确实使用了 OPTION 请求,但我已经使用 curl
确认仍会为这些请求类型返回 JSON。
问题是下面的 jQuery 中的 console.log()
Firebug 调用似乎从未运行过! getJSON 调用之前的那个。没有回调工作对我来说是个问题,因为我希望以这种方式轮询芹菜工作状态并根据工作状态做各种事情。
<script type="text/javascript">
var job_id = 'a8f25420-1faf-4084-bf45-fe3f82200ccb';
// wait for the DOM to be loaded then start polling for conversion status
$(document).ready(function()
var getConvertStatus = function()
console.log('getting some status');
$.getJSON("https://celeryserver.mydomain.com/done/" + job_id,
function(data)
console.log('callback works');
);
setInterval(getConvertStatus, 3000);
);
</script>
我使用curl
来确定我从服务器接收到的内容:
$ curl -D - -k -X GET https://celeryserver.mydomain.com/done/a8f25420-1faf-4084-bf45-fe3f82200ccb
HTTP/1.1 200 OK
Server: nginx/0.6.35
Date: Mon, 27 Jul 2009 06:08:42 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
"task": "executed": true, "id": "a8f25420-1faf-4084-bf45-fe3f82200ccb"
JSON 对我来说看起来不错,JSONlint.com 现在会为我验证它...我还使用 -X OPTION
模拟了 jQuery 查询,并从服务器返回的数据与使用 GET(内容类型应用程序/json 等)
我已经盯着这个看很久了,非常感谢任何帮助。我是一个非常新的 jQuery 用户,但这似乎应该没有问题,所以我不知道我做错了什么!
【问题讨论】:
嘿,马克!我对您为此编写的前端代码非常感兴趣,因为我一直想编写 celery 的通用 javascript 部分。欢迎您对此分享任何想法和代码。 【参考方案1】:您是从另一个域获取 JSON 吗?如果是这样,您很可能会遇到跨域问题。您需要使用 JSONP。 jQuery 会自动执行此操作,但服务器需要知道这一点。
见:
http://www.ibm.com/developerworks/library/wa-aj-jsonp1/
【讨论】:
不,同一个域;带有 jQuery 的页面从 www.mydomain.com 提供,getJSON 调用正在从 xyz.mydomain.com 检索 JSON 这算作单独的域——跨域策略即使在不同的子域上也会发挥作用。【参考方案2】:我认为你有跨子域的问题,sub.domain.tld
和 domain.ltd
不一样。
我建议您安装Firebug 并检查您的代码是否在请求开始时抛出Permission denied异常,如果是这种情况,请使用JSONP...
【讨论】:
【参考方案3】:将您的网址更改为:
"https://celeryserver.mydomain.com/done/" + job_id + "?callback=?"
然后在你的 django 视图上的结果应该是这样的:
'callback(json)'.format(callback=request.GET['callback'], json=MyJSON)
...可能有很多方法可以做到最后一行,但是 基本上读入回调参数(或任意命名)
然后将其返回为调用您的 json 对象 (jQuery 负责创建一个回调函数(它用生成的函数替换 '?'))
【讨论】:
【参考方案4】:正如一些人所说,子域算作域,我遇到了跨域问题 :)
我通过创建一小块 Django 中间件来解决这个问题,如果它们返回 JSON 并且请求附加了回调,它会更改我的视图的响应。
class JSONPMiddleware:
def process_response(self, request, response):
ctype = response.get('content-type', None)
cback = request.GET.get('callback', None)
if ctype == 'application/json' and cback:
jsonp = 'callback(json)'.format(callback=cback, json=response.content)
return HttpResponse(content=jsonp, mimetype='application/javascript')
return response
现在一切都按计划进行。谢谢!
【讨论】:
以上是关于jQuery getJSON 回调不起作用 - 即使使用有效的 JSON - 并且似乎使用的是“OPTION”请求而不是“GET”的主要内容,如果未能解决你的问题,请参考以下文章