通过 jQuery Ajax 方法访问 Node.js 服务遇到的问题
通过 jQuery Ajax 方法访问 Node.js 服务遇到的问题
疑问:请求是成功的,但是跳到 error 中执行,请问各位大侠这是怎么回事啊 直接上代码 Node.js 代码:
http.createServer(function(req, res) {
var url = parse(req.url),
pathname = url.pathname;
console.log('Request URL: http://127.0.0.1:8090' + url.href);
//解析URL参数到resource对象
req.resource = restparser.parse(pathname);
//resource.id 存在,表示是RESTful的请求
if (req.resource.id) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
restrouter.router(req, res, function(stringfyResult) {
res.end(stringfyResult);
});
} else {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
console.log('Request URL is not in RESTful style!');
res.end('Request URL is not in RESTful style!');
}
}).listen(8090, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8090/');
前端请求
$.ajax({
type: "GET",
url: "http://127.0.0.1:8090/resources/group",
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
success: function(json) {
console.log(json);
},
error: function(error) {
console.log(error);
}
});
问题描述
你提到的代码中,虽然请求成功,但仍然进入了 error
回调函数。这种情况通常是由几个潜在原因导致的,包括跨域请求、服务器返回的错误状态码或数据格式不匹配等。
分析与解决方案
跨域问题
首先检查是否是因为跨域(CORS)问题导致的。jQuery 的 dataType: "jsonp"
用于处理 JSONP 请求,这种请求类型是为了支持跨域请求。然而,如果你的服务器并没有正确处理 JSONP 请求,这可能会导致问题。
数据格式不匹配
其次,检查你的服务器返回的数据格式是否符合 jsonp
的预期。jsonp
通常需要服务器返回一个包裹在回调函数中的 JSON 对象。例如:
callback({"key": "value"});
确保你的服务器代码能够生成这样的输出。
示例代码修改
Node.js 代码
const http = require('http');
const url = require('url');
const querystring = require('querystring');
http.createServer((req, res) => {
const parsedUrl = url.parse(req.url);
const pathname = parsedUrl.pathname;
console.log(`Request URL: http://127.0.0.1:8090${parsedUrl.href}`);
// 解析 URL 参数到 resource 对象
req.resource = querystring.parse(pathname.slice(1));
// resource.id 存在,表示是 RESTful 的请求
if (req.resource.id) {
res.writeHead(200, {
'Content-Type': 'application/javascript'
});
restrouter.router(req, res, (stringfyResult) => {
res.end(`callback(${stringfyResult})`);
});
} else {
res.writeHead(400, {
'Content-Type': 'text/plain'
});
console.log('Request URL is not in RESTful style!');
res.end('Request URL is not in RESTful style!');
}
}).listen(8090, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8090/');
前端请求
$.ajax({
type: "GET",
url: "http://127.0.0.1:8090/resources/group?callback=?",
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
success: function(json) {
console.log(json);
},
error: function(error) {
console.log(error);
}
});
解释
- Node.js 代码:增加了对
req.resource.id
的判断,并且确保当请求成功时,返回的数据被包裹在一个回调函数中。 - 前端请求:确保
dataType
设置为"jsonp"
,并且在 URL 中包含callback=?
,以让 jQuery 自动处理 JSONP 的回调函数名。
这样可以确保前端能够正确接收到后端返回的数据,并进入 success
回调函数。如果问题仍然存在,请检查网络请求的具体细节,例如 HTTP 状态码和响应头信息。
你…
用 JSONP…你服务端没实现啊… JSONP 的标准啊…能不报错吗…
…嗯…简单说一下 JSONP 吧… 你 jQuery Ajax 过来.应该会用一个 callback 参数的你输出的时候得 用 callback 的值包一层…
例如
?callback=xxx
你返回的时候得
xxx(你的内容)
就像楼上说的,你用的是JSONP。 AJAX 和 JSONP 是不一样的。由于AJAX无法跨域请求。所以才产生的JSONP。 看你的代码,不存在跨域的问题。所以dataType那里直接用"json"就行。
当然,如果你一定要用jsonp的话,就像楼上说的,服务器端实现callback。
我监听了8090端口,如果我用localhost:8090/…html访问的话会被nodejs监听到,所以我用了跨域,请问该怎么避免node监听我地址栏的html请求呢
嗯,谢谢指出问题,之前一直没用过跨域的访问,这次因为我node监听了8090端口,如果我使用http://…:8090/…html 来访问的话会被node监听一次,请问这个可以避免吗
根据你的描述,问题可能出在 dataType: "jsonp"
上。jsonp
主要用于解决浏览器同源策略限制,使得客户端可以从其他域名获取数据。而你的服务器端并未实现 JSONP 的响应格式。通常,JSONP 需要在服务器端返回一个函数调用包裹的数据。
示例解决方案:
1. 修改前端代码为普通的 dataType: "json"
$.ajax({
type: "GET",
url: "http://127.0.0.1:8090/resources/group",
contentType: "application/json; charset=utf-8",
dataType: "json", // 改为普通的 json
success: function(json) {
console.log(json);
},
error: function(error) {
console.log(error);
}
});
2. 如果需要使用 JSONP,请修改 Node.js 代码
http.createServer(function(req, res) {
var url = parse(req.url),
pathname = url.pathname;
console.log('Request URL: http://127.0.0.1:8090' + url.href);
// 解析URL参数到resource对象
req.resource = restparser.parse(pathname);
// resource.id 存在,表示是RESTful的请求
if (req.resource.id) {
res.writeHead(200, {
'Content-Type': 'application/javascript'
});
restrouter.router(req, res, function(stringfyResult) {
// 假设回调函数名为 callback
const callbackName = req.query.callback || 'callback';
res.end(`${callbackName}(${stringfyResult})`);
});
} else {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
console.log('Request URL is not in RESTful style!');
res.end('Request URL is not in RESTful style!');
}
}).listen(8090, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8090/');
解释:
- 前端:将
dataType
从jsonp
改为json
可以避免不必要的复杂性。 - 后端:如果确实需要支持 JSONP,需确保服务器返回的数据被正确包装在一个 JavaScript 函数调用中。这里假设回调函数名为
callback
,你可以在请求中指定实际的回调函数名。
这样可以解决 error
回调被触发的问题。