最近在用node构建一个应用的时候用到了ajax的跨域POST请求, 使用官方标准写法
http.createServer(function (request, response) {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end('hi~');
}
会报错“未收到数据”, 但是如果把Ajax换成正常form提交,则会显示OK。
经过一番折腾终于发现原因: 一定要在服务端header里面加上”Access-Control-Allow-Origin“(允许跨域来源)
response.writeHead(200, { 'Content-Type': 'text/html', 'Access-Control-Allow-Origin' : '*' });
同时在客户端处理异常的时候也要注意 提交的dataType和返回的一定要一致 例如
$.ajax({
url: 'http://etc.xicp.net:8080/',
type: 'POST',
data:{content:content} ,
dateType:'string',
cache : false,
error: function(XMLHttpRequest, textStatus, errorThrown) {
if(XMLHttpRequest.readyState==4)
{
//alert(XMLHttpRequest.status);
//alert(XMLHttpRequest.readyState);
//alert(textStatus);
console.log('ajax error:%s',textStatus);
}
else
alert('error:'+textStatus);
},
success: function(str){
alert(str);
}
});
其实在Ajax提交的时候容易遇到两个问题 1、客户端格式解析错误 其中即使提交、返回都OK。 XMLHttpRequest.status=200(正常响应) XMLHttpRequest.readyState=4(正常接收)
ajax也会提示一个parseerror的错误。就是上面说的dataType的问题
2、POST接收的问题
习惯了.net或者asp的可能有点不习惯这里的事件驱动,最早写法是这样的
var info ='';
var content='';
request.addListener('data', function(chunk){
info += chunk;
}).addListener('end', function(){
info = querystring.parse(info);
content= info.content; });
response.writeHead(200, { 'Content-Type': 'text/html', 'Access-Control-Allow-Origin' : '*' });
response.end(content);
结果发现总是输出不了content,最后发现是事件驱动的问题 data提交是一个异步过程,会不断地触发data事件,所以end事件响应要晚于request事件。 按照官方文档的要求”每个请求都要有一个 response.end 响应标记结束。这个响应必须放在 ends事件的向应里,既下面这个函数里
addListener('end', function(){
实际上这两个问题都并不完全是Node本身问题,不过估计很多入门的同学还是会遇到,在此Mark一下。方便查询
确实值得mark一下
-
是因为老版本的浏览器不支持跨域ajax提交数据(同源策略),现代化的浏览器增加了类似flash的Access-Control 来支持跨域通讯,方便信任域之间的通讯。而这种机制的实现,是基于http header实现。
-
POST提交的数据,接收的时候是chunk形式出现,和通常的web编程不太一样。chunk是二进制流,得用buffer拼接, 不能直接用 info += chunk 的形式,这样会导致乱码的
3Q,补充的对。要用Buffer
如果是中文数据,建议使用小田(Jackson Tian/朴灵)的bufferhelper,这可以避免在chunk拼接是出现的乱码。webjs的流系统就是使用bufferhelper实现的~
谢谢,不知道现在Node内存Buffer的管理如何了,去年看到路线图说这里效率还是有点差