我正在尝试使用简单的jQuery get JSON调用。我的成功处理程序非错误处理程序似乎都没有被调用。 Firebug还将数据体显示为空。
服务器是在web.py下运行的非常基本的代码。我已经使用lynx连接到服务器测试了服务器,它下载了json数据OK。
这是jQuery:
$(document).ready(function() {
$.ajax({
url: 'http://localhost:8080/settings.json',
cache: false,
success: function(json){
alert('json success ' + json);
},
error: function(xhr, textStatus, errorThrown) {
alert(xhr.statusText);
}
});
});
JSON data is:
{"netmask": "255.255.0.0", "ipaddress": "192.168.1.153"}
答案 0 :(得分:7)
您无法使用XmlHttpRequest向另一个域(该规则包含不同的端口)发出请求,same origin policy会阻止该请求。
尝试执行此操作的结果是空响应,因此您无法看到内容。出于安全考虑,这只是一个规则......如果您要连接到同一个主机和端口,那么这不是问题。
答案 1 :(得分:1)
您可以在Apache中设置反向代理,使远程数据源看起来像来自本地域。我写了一篇关于如何做到这一点的博客文章:
答案 2 :(得分:0)
我找到了一种解决方法,可以在跨域请求中使用空响应来获取错误回调。
在这个例子中,我使用Zepto,一个轻量级的jQuery版本,但我认为这在jQuery中也可以正常工作。
首先,您必须使用这些参数来执行跨域请求:
$.ajax({
url: url,
type: 'GET',
dataType: 'jsonp',
contentType: 'application/x-javascript',
crossDomain: true,
success: function (data, status) { /* ... */ }
error: function () { /* ... */ }
// ...
现在, $。ajax 功能在内部使用 $。ajaxJSONP 进行跨域请求。这是原始的Zepto $。ajaxJSONP 功能:
$.ajaxJSONP = function(options){
var callbackName = 'jsonp' + (++jsonpID),
script = document.createElement('script'),
abort = function(){
$(script).remove()
if (callbackName in window) window[callbackName] = empty
ajaxComplete('abort', xhr, options)
},
xhr = { abort: abort }, abortTimeout
if (options.error) script.onerror = function() {
xhr.abort()
options.error()
}
window[callbackName] = function(data){
clearTimeout(abortTimeout)
$(script).remove()
delete window[callbackName]
ajaxSuccess(data, xhr, options)
}
serializeData(options)
script.src = options.url.replace(/=\?/, '=' + callbackName)
$('head').append(script)
if (options.timeout > 0) abortTimeout = setTimeout(function(){
xhr.abort()
ajaxComplete('timeout', xhr, options)
}, options.timeout)
return xhr
}
我的解决方法非常简单,包含在script.onload事件处理程序上调用几次的间隔,以验证是否调用了回调函数。
这是 $。ajaxJSONP 功能的我的版本:
$.ajaxJSONP = function(options){
var called = false, // Flag to check that callback was called
callbackName = 'jsonp' + (++jsonpID),
script = document.createElement('script'),
abort = function(){
$(script).remove()
if (callbackName in window) window[callbackName] = empty
ajaxComplete('abort', xhr, options)
},
xhr = { abort: abort }, abortTimeout
if (options.error) {
script.onerror = function() {
xhr.abort()
options.error()
};
// IMPORTANT!!!
script.onload = function () {
var times = 0;
var interval = setInterval(function () {
// After 5 intervals, if the callback wasn't called, returns an error
if (times++ == 5) {
clearInterval(interval);
if (!called) {
options.error();
}
} else if (called) {
clearInterval(interval);
}
}, 100);
};
}
window[callbackName] = function(data){
// Setting the "called" flag to true
called = true;
clearTimeout(abortTimeout)
$(script).remove()
delete window[callbackName]
ajaxSuccess(data, xhr, options)
}
serializeData(options)
script.src = options.url.replace(/=\?/, '=' + callbackName)
$('head').append(script)
if (options.timeout > 0) abortTimeout = setTimeout(function(){
xhr.abort()
ajaxComplete('timeout', xhr, options)
}, options.timeout)
return xhr
}
注意:如果您对服务器端行为感兴趣,请参阅本教程的开头:http://phonegap.com/2011/07/20/making-jsonp-calls-with-zepto-on-android-device/