只有刷新页面后,才能更新Firebase存储中的logging

在我的collections中修改Firebase中的logging并更改图片时,它将在Firebase和Google云端平台(存储)中成功更新,但在模板中我无法看到更改,除非我刷新页面。 我得到的错误是: Error: Can't set headers after they are sent.

 router.get('/edit/:id', function(req, res) { var id = req.params.id; firebase.database().ref(`collection/` + id).once('value') .then(function(data) { res.render('myEditTemplate', { id: id, collectionRecords: data.val() }); }) .catch(function(error) { res.render('error', { error: error }); }); }); router.post('/edit', upload.single('image'), function(req, res) { var id = req.body.id; var name = req.body.name; var image = req.file; if (!req.file) { console.log('no image has been uploaded'); firebase.database().ref(`collection/` + id).update({ 'name': name, }); } else { console.log('image successfully uploaded'); var filePath = id + ".jpg"; fs.rename(req.file.path, filePath, function(err) { if (err) { return res.render("error", { err: err }); } var myPath = 'collection/' + filePath; var storageFile = bucket.file(myPath); var storageFileStream = storageFile.createWriteStream({ metadata: { contentType: req.file.mimetype } }); storageFileStream.on('error', function(err) { return res.render("error", { error: err }); }); storageFileStream.on('finish', function() { storageFile.makePublic(function(err, data) { if (err) { return res.render("error", { err: err }); } }); fs.unlink(filePath, function(err) { console.error(err); }); firebase.database().ref(`collection/` + id).update({ 'name': name, 'image_id': filePath }); }); fs.createReadStream(filePath).pipe(storageFileStream); }); } res.redirect('/collection'); }); 

当你得到这样的错误,这意味着你不止一次地发送响应给客户端(特别是设置标题 )。

在这种情况下,错误的来源是res.redirect(...)res.render(...)

 router.post('/edit', upload.single('image'), function(req, res) { var id = req.body.id; var name = req.body.name; var image = req.file; ... // Eventually update the file in Google Cloud Storage // This happens in an async way. ... // This will be always called first res.redirect('/collection'); }); 

如果asynchronous操作发生错误,则会出现您提到的错误。 它只是无法渲染错误模板,因为你已经做了redirect(...)

你目前的时间表如下所示:

  ___ Update the image in GC __ / \ |--*-----*--*----------------------------*------> | | Is there an error? Request | If so, res.render(...) | Rendering the error template res.redirect(...) will always fail due to the | previous res.redirect(...) | V You do not see the new image at this moment, because it's simply not updated yet. 

它应该发生什么是:

  ___ Update the image in GC __ / \ |--*-----*-------------------------------*------> | Is there an error? Request If so, show the error: res.render(...) If not, do the redirect: res.redirect(...) | V Since the page is going to load *after* the image was updated you will see the updated image. 

代码将如下所示:

 router.post('/edit', upload.single('image'), function(req, res) { var id = req.body.id; var name = req.body.name; var image = req.file; if (!req.file) { console.log('no image has been uploaded'); firebase.database().ref(`collection/` + id).update({ 'name': name, }).then(function() { res.redirect('/collection'); }).catch(function(err) { res.render("error", { err: err }); }) } else { console.log('image successfully uploaded'); var filePath = id + ".jpg"; fs.rename(req.file.path, filePath, function(err) { if (err) { return res.render("error", { err: err }); } var myPath = 'collection/' + filePath; var storageFile = bucket.file(myPath); var storageFileStream = storageFile.createWriteStream({ metadata: { contentType: req.file.mimetype } }); storageFileStream.on('error', function(err) { return res.render("error", { error: err }); }); storageFileStream.on('finish', function() { storageFile.makePublic(function(err, data) { if (err) { return res.render("error", { err: err }); } res.redirect('/collection'); }); fs.unlink(filePath, function(err) { console.error(err); }); firebase.database().ref(`collection/` + id).update({ 'name': name, 'image_id': filePath }); }); fs.createReadStream(filePath).pipe(storageFileStream); }); } });