请教一个在http.request response事件中的嵌套data事件中http跳转问题(已解决,statusCode错误地取默认值200所致)
发布于 10 年前 作者 lanyuliuyun 12252 次浏览 最后一次编辑是 8 年前

我按照如下流程执行了一序列的嵌套操作 1,普通的get请求handler ↓ 2,发起post请求 ↓ 3,post请求的response事件的handler ↓ 3,注册post请求的response对象的data事件 ↓ 4,data事件中使用1中的response对象通过setHeader执行跳转

但实际的结果是在浏览器端仍然停留在1中的请求上,并没有执行4中所执行的跳转。本人也是刚开始学习nodejs,不明白问题出在哪里。恳请对此熟悉的大侠指点一下!先谢过!

8 回复

补充一下4中有设置statusCode和end()调用,没有遗漏什么东西

感谢朴灵的回复,代码如下

app.get('/weibo', function(req, res){
	if (!req.query.code)
	{
		console.log(req.query);
		res.statusCode = 400;
		res.end('error: '+req.query.error_description);
		return;
	}

	var data = ['client_id='+weibo.config.client_id,
		   	   'client_secret='+weibo.config.client_secret,
		   	   'grant_type=authorization_code',
		   	   'redirect_uri='+weibo.config.redirect_uri,
		   	   'code='+req.query.code].join('&');
	httpclient.post('https://api.weibo.com/oauth2/access_token', data, function(resp){
		console.log('weibo.token string: '+resp);
		weibo.token = JSON.parse(resp);
		console.log('weibo.token.access_token: '+weibo.token.access_token);
		console.log('now we will go back to /');
		res.statucCode = 302;
		res.setHeader('Location', '/');
		res.end();
	});
});

/weibo是weib open api的回调uri,是正常从 https://api.weibo.com/oauth2/authorize 跳转回来的,实际console打印中有 weibo.token string: weibo.token.access_token: now we will go back to / 的输出,但是没有跳转;app.get()实现是《深入浅出nodejs》中的example,就不列举了;httpclient是对http.request/https.request直观的封装,代码如下

var httpclient = {};
httpclient.post = function(u, data, callback){
	var urlparts = url.parse(u, true);
	var request;
	if (urlparts.protocol === 'http:')
	{
		request = http.request({
			hostname: urlparts.host,
			port: urlparts.port || 80,
			method: 'POST',
			path: urlparts.pathname
		});		
	}
	else if (urlparts.protocol === 'https:')
	{
		request = https.request({
			hostname: urlparts.host,
			port: urlparts.port || 443,
			method: 'POST',
			path: urlparts.pathname
		});
	}
	else
	{
		console.error('unsupported protocol: '+urlparts.protocol);
		return;
	}

	request.on('response', function(res){
		res.on('data', function(d){
			callback(d.toString());
		});
	});
	request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
	request.setHeader('Content-Length', data.length);
	request.end(data);
}

module.exports = httpclient;

@lanyuliuyun 很有意思的问题。

  • 客户端发出的GET /weibo,是不是一个Ajax请求?
  • 打开Chrome浏览器开发者工具,转到"Network"页面,然后重新走一遍请求流程,在"Network"页面中查看服务器返回的响应是什么。可能客户端已经收到服务器返回的跳转响应,只是它没有跳转而已。

@bnuhero 不是ajax请求,是 https://api.weibo.com/oauth2/authorize 响应中Location的header跳过来的,如下 HTTP/1.1 302 Moved Temporarily Server: nginx/1.2.0 Date: Mon, 30 Jun 2014 11:46:37 GMT Content-Length: 0 Connection: keep-alive Pragma: No-cache Cache-Control: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Api-Server-IP: 10.75.25.115 Location: http://127.0.0.1/weibo?state=weibo&code=xxxxxxxxxxx 已经在Chrome中如此跟过了,在/weibo的响应中的确有Location: /的header,但statusCode竟然是200,而不是预期的302,如下 HTTP/1.1 200 OK Location: / Date: Mon, 30 Jun 2014 11:46:36 GMT Connection: keep-alive Transfer-Encoding: chunked 我想没能跳转应该是和这个有直接关系吧!

@bnuhero @Jackson 抱歉是因为一个很弱智的错误!最终跳转时statusCode错写成res.statucCode,修正后解决了! 如此看来,若没有明确指定response的statusCode,在调用end()之后,默认成200了?

解决了就好,我还特意去翻了翻Express框架中response.redirect()的实现代码,呵呵。

@bnuhero 仍然谢谢!还是因为对nodejs不熟悉。要去安心学习了!

回到顶部