이것이 1000 번 응답 된 것을 알고 있지만 내 인생에서 왜 헤더를 두 번 이상 보내려고하는지 알 수 없습니다. 따라서 중복으로 표시하려는 경우 중복 이유와 내가 잘못한 부분을 설명하십시오. 약간의 설명 없이는 링크가 거의 도움이되지 않습니다.
알겠습니다. 확인 링크를 두 번 클릭하여 사용자에게 복제를 시도하기 위해 확인 토큰을 두 번 다시 보내려고 할 때 미들웨어/컨트롤러를 실행하는 간단한 확인 경로가 있습니다.
사용자의 토큰은 여전히 내 DB에 있지만 (이를 변경할 계획이지만) 오류를 일으키는 줄은 사용자 프로필을 확인하여 확인되었는지 확인하기 때문에 중요하지 않습니다.
router.post('/confirmation',
user.confirmationPost);
exports.confirmationPost = function (req, res, next) {
// Find a matching token
Token.findOne({ token: req.body.token }, function (err, token) {
if (!token) return res.status(400).send({ type: 'not-verified', message: 'We were unable to find a valid token. Your token my have expired.' });
// If we found a token, find a matching user
User.findOne({ _id: token._userId }, function (err, user) {
if (!user) return res.status(400).send({ message: 'We were unable to find a user for this token.' });
if (user.isVerified) return res.status(400).send({ message: 'This user has already been verified.' }); // THIS LINE CAUSES THE ERROR
// Verify and save the user
user.isVerified = true;
user.save(function (err) {
if (err) { return res.status(500).send({ message: err.message }); }
res.redirect(`${config.siteURL}/dash`);
});
});
});
next();
};
오류 메시지
Error: Can't set headers after they are sent.
- 답변 # 1
- 답변 # 2
새로운 대기/비동기 사용을 제안하십시오. 콜백 스타일은 오류가 발생하기 쉽습니다. 비동기 제어를 정렬하는 데 어려움이 있습니다.
Express 프레임 워크는 콜백 스타일이므로 https://github.com/tj/co를 사용할 수 있습니다 처리기 사용 대기/비동기, 그러나 마지막으로 http://koajs.com/이 더 좋습니다.
- 답변 # 3
문제를 파악한 후 응답을 정답으로 표시하십시오!
앞으로 ES7의 async/await 구문을 사용하여 코드 스 니펫을 작성했습니다. 코드가 더 길어 보일 수 있지만 이해하기 쉬워야합니다. 또한 모든 반환 기능을 확장하고 주석을 추가하여 길이에 기여했습니다.
/* * Notice how the keyword `async` is in front of the arrow function. * This tags the function as asynchronous and returns a promise. * It also allows us to use the `await` keyword which waits for the function * to return whatever follows the await keyword. Only after it returns will * the function continue. */ exports.confirmationPost = async (req, res, next) => { // The await keyword here makes sure that Token.findOne() returns (resolves/rejects promise) before continuing the function. // However, this DOES NOT mean that the program hangs, as it would for a synchronous function. // Other functions can run while this instance of the function waits for Token.findOne() to return. let token = await Token.findOne({ token: req.body.token }); // Once Token.findOne returns, you have access to a then callback. token.then((err, token) => { if (!token) { // While this is completely fine, I suggest you use next() and pass in an error obj to it and let your middleware handle the return of the error to the client. return res.status(400).send({ type: 'not-verified', message: 'We were unable to find a valid token. Your token my have expired.' }); } // Once again, we use await to wait for User.findOne() to return. let user = await User.findOne({ _id: token._userId }); // Once User.findOne returns, you have access to a then callback. user.then((err, user) => { if (!user) { return res.status(400).send({ message: 'We were unable to find a user for this token.' }); } if (user.isVerified) { return res.status(400).send({ message: 'This user has already been verified.' }); } // Verify and save the user user.isVerified = true; // You can simply chain the then callback instead of making a new variable. user.save().then(err => { if (err) { return res.status(500).send({ message: err.message }); } res.redirect(`${config.siteURL}/dash`); }); }); }); }
약속을 사용하고 노드 및 몽고와 비동기/대기 할 때 머리에 못을 박는 아래 두 링크를 확인하십시오.
<올>https://medium.com/@rossbulat/using-promises-async-await-with-mongodb-613ed8243900
http://www.codingpedia.org/ama/cleaner-code-in-nodejs-with-async-await-mongoose-calls-example
관련 자료
- c - h 파일에 이미 포함 된 헤더를 기본 파일에 포함해야합니까?
- node.js - 함수 반환은 반환되지 않지만 정지
- c# - Serilog는 콘솔에 로그하지만 파일에는 로그하지 않습니다
- php - Xamp에서는 작동하지만 라이브 서버에서는 작동하지 않는 코드
- c# - RedirectToAction에 도달했지만 경로 재 지정되지 않음
- javascript - Dev에는 설정되었지만 Prod에는 설정되지 않은 쿠키
- node.js - localhost - 4000에서 실행되지만 ec2-ip : 4000에서는 실행되지 않습니다
- typescript - "any"와 일치하지만 배열은 일치하지 않습니다
- postgresql - NOT NULL 인 경우 FK로 사용되지 않는 경우에만 쿼리
- python - pandaserrorsEmptyDataError이지만 파일이 비어 있지 않습니다
- php - AJAX를 통해 전송 된 데이터는 $_POST에서 사용할 수 없습니다
- java - 데이터가 아닌 XML 태그 제거
- ios - UITabViewController의 일부 탭을 재정렬 가능하게 만드십시오
- python - Int 객체는 아래 첨자가 가능하지 않지만 목록입니다
- react native - 세트에서 요소를 추가하지만 제거 할 수없는 이유
- javascript - 이미 시스템에있는 헤더와 비교하기 위해 CSV에서 테이블로 헤더를로드하는 방법이 있습니까?
- 도커 파일을 찾을 수 없지만 볼 수 있습니다
- arrays - C로 코드를 작성했지만 작동하지 않습니까?
- java - list toArray ()를 수행 할 수 있지만 list toArray ()는 수행 할 수없는 이유
- debian - Python3이 설치되지 않았지만 설치됨
- node.js : "?"뒤에 GET 매개 변수에 액세스하는 방법 Express에서?
- html : Expressjs에서 Get 메서드를 사용하는 방법
- node.js : 응답 이후에 두 번째 기능을 실행하지 못하게하는 방법
- node.js : React Client에서 SocketIO 비공개 메시지를 청취하는 방법은 무엇입니까?
- node.js : Apollo Server Reseting Cors 옵션
- javascript : 내 HTML은 다른 폴더에 해당 링크를 표시 할 수 없습니다 (node.js)
- javascript : 요청에 응답 한 후 console.log 통화가 실행됩니다
- node.js : NodeJS API에서 가져 오지 않는 Express
- node.js : NodeJS 기능을 스팸 방지하는 방법은 무엇입니까?
- node.js : Firestore 호출 중에 Firebase-admin을 사용하여 사용자를 가장 할 수 없습니다.
내 문제를 알아 냈는데 문제는
next()
였습니다. 결국, 헤더를 다시 전달/설정하려고 시도한 res.send/json 이후에 호출되었습니다.