2016-10-28 15 views
1

Firebaseでコレクション内のレコードを編集して画像を変更すると、FirebaseとGoogle Cloud Platform(ストレージ)で正常に更新されますが、私はページを更新しない限り変更を見ることができます。私が手にエラーがある:あなたがこのようなエラーを取得している場合はError: Can't set headers after they are sent.ページを更新した後にしか表示されないfirebase storage内のレコードを更新する

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'); 
}); 
+0

"エラー:ヘッダーが送信された後にヘッダーを設定できません"というのは、要求が既に送信された後にその要求への応答を送信しようとしていることを意味します送られた。あなたのケースでは、非同期タスクが実行される前にリダイレクトを作成しているので、エラーが発生したときはいつでも、要求に対する2番目の応答を送信しようとしています。 – krakig

答えて

1

、それはあなたが(具体的には、はヘッダ設定)回以上のクライアントへの応答を送信していることを意味します。

この場合のエラーの原因は、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'); 
}); 

非同期操作からエラーが発生した場合は、上記のエラーが発生します。 がすでにになっているので、単にエラーテンプレートをレンダリングできません。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); 
    }); 
    } 
}); 
関連する問題