发送到客户端后无法设置标头

时间:2021-03-22 05:41:52

标签: node.js

我正在创建一个 api,它将在 nodejs 中使用 python-shell 调用 python 脚本。但是,当我运行该 api 时,该 api 返回“无法设置标头后将它们发送到客户端”的错误。下面是api的代码。

app.post(
    "/uploadFacial",
    multer({
      storage: storage
    }).single('upload'), function(req, res) {
      console.log(req.file.filename);
      var userid = req.body.upload[1];
      console.log("User id: "+userid);

      var success = true;
      var message = '';

      var subStringUserId = userid.substring(1,userid.length-1);
      var dir = "./users/"+subStringUserId;

      //res.setHeader("Content-Type", "application/json");
      
      console.log(dir);
      if (!fs.existsSync(dir)){
        fs.mkdirSync(dir);
        success = false;
        message = 'Cannot detect the person.Please add name in the textbox provided below to save the person.';
        res.status(200).json({message: message,success:success});
        res.end();
      }else {
        console.log("in else");
        var options={
          mode:'text',
          encoding:'utf-8',
          pythonOptions:['-u'],
          scriptPath:'./',
          pythonPath:'',
          args:[subStringUserId,req.file.filename]
        }
        var facialScript = new PythonShell('face_detect.py',options)
        facialScript.on('message',(response)=>{
          console.log(response);
          res.status(200).send(response);
          //res.end();
        
        })

        facialScript.on('error',(err)=>{
          console.log(err);
        })
      }
    });

如果需要,下面是python代码

from deepface import DeepFace
from os.path import join, dirname, realpath
import os, sys
import json


PARENT_DIR = join(dirname(realpath(__file__)), './users/')
TEST_DIR = join(dirname(realpath(__file__)), './uploads/')

print(json.dumps({'success':False,'message':'Cannot detect at moment.Please try later'})) #this is only for debugging
user_id = sys.argv[1] 


img_name = sys.argv[2]


db = os.path.join(PARENT_DIR, user_id)
img = os.path.join(TEST_DIR, img_name)

try:
    df=DeepFace.find(img_path=img,db_path=db, model_name = "Facenet")

    if(df.size==0):
        print(json.dumps({'message': 'Cannot detect the person.Please add name in the textbox provided below to save the person.','success':False}))
    else:
        print(json.dumps({'success':True,'message':os.path.splitext(os.path.basename(df['identity'][0]))[0]}))        
        
         
except Exception as e: 
    #logger.error('Failed to upload to ftp: '+ str(e))
    a = 1

这里是错误

 throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (/Users/priyamvora/Node/Drishti/ImageUploadTest/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/priyamvora/Node/Drishti/ImageUploadTest/node_modules/express/lib/response.js:170:12)
    at PythonShell.facialScript.on (/Users/priyamvora/Node/Drishti/ImageUploadTest/multipart.js:129:27)
    at PythonShell.emit (events.js:182:13)
    at /Users/priyamvora/Node/Drishti/ImageUploadTest/node_modules/python-shell/index.js:324:22
    at Array.forEach (<anonymous>)
    at PythonShell.receiveInternal (/Users/priyamvora/Node/Drishti/ImageUploadTest/node_modules/python-shell/index.js:322:15)
    at PythonShell.receive (/Users/priyamvora/Node/Drishti/ImageUploadTest/node_modules/python-shell/index.js:296:21)
    at Socket.emit (events.js:182:13)

请尽早帮助。

2 个答案:

答案 0 :(得分:2)

如果执行此 if 循环,将发送响应

if (!fs.existsSync(dir)){
        fs.mkdirSync(dir);
        success = false;
        message = 'Cannot detect the person.Please add name in the textbox provided below to save the person.';
        res.status(200).json({message: message,success:success});
        res.end();

响应也在尝试发送以下代码

var facialScript = new PythonShell('face_detect.py',options)
        facialScript.on('message',(response)=>{
          console.log(response);
          res.status(200).send(response);
          //res.end();
        
        })

没有包含在 else 循环中。

答案 1 :(得分:1)

这是因为“消息”事件侦听器被多次触发,这就是为什么 res.status(200).send(response); 行执行不止一次导致此问题的原因。尝试将事件侦听器的结果累积在一个变量中并发送响应(仅一次)。 像这样:

let result="";
 facialScript.on('message',(response)=>{
         result=result+response;//assuming that response is string you can change this as per your convenience .
        
        })

facialScript.on("end",()=>{
res.send(result);
})

此外,您还必须删除 if 条件中的 res.status(200).json({message: message,success:success}); 以识别目录是否存在!!