我对 Node.js 还很陌生,但遇到了一些问题。
我正在使用 Node.js 4.10 和 Express 2.4.3。
当我尝试访问http://127.0.0.1:8888/auth/facebook时,我将被重定向到http://127.0.0.1:8888/auth/facebook_callback。
然后我收到以下错误:
Error: Can't render headers after they are sent to the client. at ServerResponse.<anonymous> (http.js:573:11) at ServerResponse._renderHeaders (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:64:25) at ServerResponse.writeHead (http.js:813:20) at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/auth.strategies/facebook.js:28:15 at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:113:13 at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/strategyExecutor.js:45:39) at [object Object].pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:32:3) at [object Object].halt (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:29:8) at [object Object].redirect (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:16:8) at [object Object].<anonymous> (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/auth.strategies/facebook.js:77:15) Error: Can't set headers after they are sent. at ServerResponse.<anonymous> (http.js:527:11) at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:195:11) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23) at param (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:189:13) at pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:191:10) at Object.router [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:197:6) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15) at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7) Error: Can't set headers after they are sent. at ServerResponse.<anonymous> (http.js:527:11) at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23) at param (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:189:13) at pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:191:10) at Object.router [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:197:6) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15) at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7) Error: Can't set headers after they are sent. at ServerResponse.<anonymous> (http.js:527:11) at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9) at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15) at HTTPServer.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:211:3) at Object.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:105:14) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15) Error: Can't set headers after they are sent. at ServerResponse.<anonymous> (http.js:527:11) at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9) at HTTPServer.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:211:3) at Object.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:105:14) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15) at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:323:9 at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9 node.js:134 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Can't set headers after they are sent. at ServerResponse.<anonymous> (http.js:527:11) at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13) at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9) at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:323:9 at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9 at Array.<anonymous> (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session/memory.js:57:7) at EventEmitter._tickCallback (node.js:126:26)
以下是我的代码:
var fbId= "XXX"; var fbSecret= "XXXXXX"; var fbCallbackAddress= "http://127.0.0.1:8888/auth/facebook_callback" var cookieSecret = "node"; // enter a random hash for security var express= require('express'); var auth = require('connect-auth') var app = express.createServer(); app.configure(function(){ app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser()); app.use(express.session({secret: cookieSecret})); app.use(auth([ auth.Facebook({ appId : fbId, appSecret: fbSecret, callback: fbCallbackAddress, scope: 'offline_access,email,user_about_me,user_activities,manage_pages,publish_stream', failedUri: '/noauth' }) ])); app.use(app.router); }); app.get('/auth/facebook', function(req, res) { req.authenticate("facebook", function(error, authenticated) { if (authenticated) { res.redirect("/great"); console.log("ok cool."); console.log(res['req']['session']); } }); }); app.get('/noauth', function(req, res) { console.log('Authentication Failed'); res.send('Authentication Failed'); }); app.get('/great', function( req, res) { res.send('Supercoolstuff'); }); app.listen(8888);
我可以知道我的代码有什么问题吗?
Express 中的res对象是Node.js 的http.ServerResponse子类(阅读 http.js 源代码)。您可以随时拨打电话res.setHeader(name, value),直到您拨打电话为止res.writeHead(statusCode)。之后writeHead,标头被烘烤,您只能调用res.write(data),最后res.end(data)。
res
http.ServerResponse
res.setHeader(name, value)
res.writeHead(statusCode)
writeHead
res.write(data)
res.end(data)
错误“错误:发送后无法设置标头。” 表示您已经处于 Body 或 Finished 状态,但某些函数试图设置 header 或 statusCode。当您看到此错误时,请尝试查找在某些正文已写入之后尝试发送标头的任何内容。例如,查找意外调用两次的回调,或在发送正文后发生的任何错误。
在您的情况下,您调用res.redirect()了 ,这导致响应变为 Finished。然后你的代码抛出了一个错误(res.reqis null)。并且由于错误发生在您的实际中function(req, res, next)(而不是在回调中),Connect 能够捕获它,然后尝试发送 500 错误页面。但是由于标头已经发送,Node.jssetHeader抛出了您看到的错误。
res.redirect()
res.req
null
function(req, res, next)
setHeader
响应必须在 Head 中并保持在 Head 中:
res.writeContinue()
res.statusCode = 404
res.getHeader(name)
res.removeHeader(name)
res.header(key[, val])
res.charset = 'utf-8'
res.contentType(type)
响应必须在 Head 中并变为 Body :
res.writeHead(statusCode, [reasonPhrase], [headers])
响应可以在 Head/Body 中并保留在 Body 中:
res.write(chunk, encoding='utf8')
响应可以在 Head/Body 中并变为 Finished :
res.end([data], [encoding])
响应可以是 Head/Body 并保持其当前状态:
res.addTrailers(headers)
响应必须在 Head 中并变为 Finished :
return next([err])
res.send(body|status[, headers|status[, status]])
res.attachment(filename)
res.sendfile(path[, options[, callback]])
res.json(obj[, headers|status[, status]])
res.redirect(url[, status])
res.cookie(name, val[, options])
res.clearCookie(name[, options])
res.render(view[, options[, fn]])
res.partial(view[, options])