簡體   English   中英

Node.js中的錯誤:將標頭發送到客戶端后無法設置標頭

[英]Error in nodejs : Cannot set headers after they are sent to the client

我正在使用HTML和nodejs創建一個簡單的表單。 該表格接收電子郵件和密碼這兩個數據,並根據代碼中編寫的功能運行。

我的程序中有兩個文件app.jsindex.html

app.js

const _ = require('lodash');
const express = require('express');
const path = require('path');
const Joi = require('joi');
const bodyParser = require('body-parser');
const app = express();

app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.get('/',(req,res)=>{

    res.sendFile(path.join(__dirname,'index.html'));

});

app.get('/example',(req,res)=>{

    res.send('Hitting Example Route');

});

app.get('/example/:name/:age',(req,res)=>{

    console.log(req.params);
    console.log(req.query);
    //res.send('example with route params');
    res.send(req.params.name+":"+req.params.age);

});

app.post('/',(req,res)=> {
    console.log(req.body);
    const schema = Joi.object().keys({

        email : Joi.string().trim().email().required(),
        password : Joi.string().min(5).max(10).required()
    });

    Joi.validate(req.body,schema,(err,result)=>{
        if(err)
        {
            console.log(err);
            res.send('An error has occured');
        }
        console.log(result);
        res.send('Successfully posted data');

    });
    //database work here

    //res.json({success:true});

});

app.listen(3000);

index.html

<!DOCTYPE html>
<html>

   <head>
      <title>Text Input Control</title>
   </head>

   <body>
      <!--<form !action="/"></form> method="POST" id="form">-->
      <form  method="POST" id="form">

         First name: <input type = "text" name = "first_name" />
         <br>
         Last name: <input type = "text" name = "last_name" />

         <input type="submit" value="Submit">

      </form>

            <script
        src="http://code.jquery.com/jquery-3.3.1.js"
        integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
        crossorigin="anonymous"></script>

        <script>
            $(document).ready(()=>{
                $('#form').submit((e)=>{
                    e.preventDefault({});
                    $.ajax({

                        url : '/',
                        type : 'post',
                        contentType : 'application/json',
                        data : JSON.stringify($('#form').serializeArray()),
                        success : (response)=>{

                            console.log('Successfuly got response');
                            console.log(response);

                        }

                    });

                });


            });

        </script>

   </body>

</html>

我收到一條錯誤消息,指出Cannot set headers after they are sent to the client 我該如何修復代碼?

錯誤:

PS F:\DatabaseProject8> node app.js
[ { name: 'first_name', value: 'hello@gmail.com' },
  { name: 'last_name', value: 'gredyjht' } ]
{ ValidationError: "value" must be an object
    at Object.exports.process (F:\DatabaseProject8\node_modules\joi\lib\errors.js:203:19)
    at internals.Object._validateWithOptions (F:\DatabaseProject8\node_modules\joi\lib\types\any\index.js:764:31)
    at module.exports.internals.Any.root.validate (F:\DatabaseProject8\node_modules\joi\lib\index.js:147:23)
    at app.post (F:\DatabaseProject8\app.js:40:9)
    at Layer.handle [as handle_request] (F:\DatabaseProject8\node_modules\express\lib\router\layer.js:95:5)
    at next (F:\DatabaseProject8\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (F:\DatabaseProject8\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (F:\DatabaseProject8\node_modules\express\lib\router\layer.js:95:5)
    at F:\DatabaseProject8\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (F:\DatabaseProject8\node_modules\express\lib\router\index.js:335:12)
  isJoi: true,
  name: 'ValidationError',
  details:
   [ { message: '"value" must be an object',
       path: [],
       type: 'object.base',
       context: [Object] } ],
  _object:
   [ { name: 'first_name', value: 'hello@gmail.com' },
     { name: 'last_name', value: 'gredyjht' } ],
  annotate: [Function] }
[ { name: 'first_name', value: 'hello@gmail.com' },
  { name: 'last_name', value: 'gredyjht' } ]
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 (F:\DatabaseProject8\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (F:\DatabaseProject8\node_modules\express\lib\response.js:170:12)
    at Joi.validate (F:\DatabaseProject8\app.js:47:13)
    at internals.Object._validateWithOptions (F:\DatabaseProject8\node_modules\joi\lib\types\any\index.js:767:20)
    at module.exports.internals.Any.root.validate (F:\DatabaseProject8\node_modules\joi\lib\index.js:147:23)
    at app.post (F:\DatabaseProject8\app.js:40:9)
    at Layer.handle [as handle_request] (F:\DatabaseProject8\node_modules\express\lib\router\layer.js:95:5)
    at next (F:\DatabaseProject8\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (F:\DatabaseProject8\node_modules\express\lib\router\route.js:112:3)

您收到有關兩次設置標題的錯誤的原因是, Joi.validate回調中發生錯誤。 您正在發送“發生了錯誤”,但是在錯誤處理程序之后,您仍在發送“成功發布數據”。 您不應調用send兩次,否則會收到該錯誤。 發生錯誤時,您應該退出Joi.validate回調。

您定義的架構可能不正確

這樣定義

const schema = {
    email: Joi.string().trim().email().required(),
    password: Joi.string().min(5).max(10).required()
};

有時我遇到了這個問題,我為res.redirect('/example')解決了res.redirect('/example') res.send

您可以嘗試的另一件事是更改if語句,是否有可能在res.send執行兩次時出錯:

if(err){
            console.log(err);
            res.send('An error has occured');
        } 
else {
        console.log(result);
        res.send('Successfully posted data'); 
}

您收到的錯誤是由於Nodejs的異步特性。 使用Promise / Async-Await來防止此類錯誤。 使用異步等待

app.post('/',async(req,res)=> {
console.log(req.body);
const schema = Joi.object().keys({

    email : Joi.string().trim().email().required(),
    password : Joi.string().min(5).max(10).required()
});

let result = await Joi.validate(req.body,schema);
if(result.err){
    console.log(err);
    res.send('An error has occured');
}else{
    console.log(result);
    res.send('Successfully posted data');
}
//database work here

//res.json({success:true});

});

這可能會做

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM