我知道,這聽起來很奇怪,但這是真的。我正坐著在 node.js 上制作一個 API,但是當我開始測驗它時,我驚訝地發現,當第一個 res.status().send() 到達時,幾乎在查詢處理開始時,VS Code 下降“在將標頭發送到客戶端后無法設定標頭”錯誤。
我如何意識到資料庫查詢是有罪的?我使用“res.finished”屬性檢查它何時“發送到客戶端”,并發現 res.finished 在資料庫查詢后從“false”變為“true”。
誰知道它可以是什么?我用 MySQL 資料庫做了同樣的 API 事情,結果很好,但現在我使用的是 PostgreSQL,所以事情開始發生了。
我從打字稿檔案中匯出“PostgreSQL 管理器”類
PostgreSQL_Manager.ts:
module.exports = {
PostgreSQL_db_manager
}
在 index.ts 中匯入并初始化:
index.ts
const PostgreSQL_mngr = require('./PostgreSQL_Manager.ts').PostgreSQL_db_manager;
const db = new PostgreSQL_mngr;
然后,如果我使用對資料庫的查詢來評論該陳述句, res.finished 保持錯誤(我嘗試使用 readRows (SELECT) 和 createRows(INSERT INTO)):
Piece of index.ts code:
console.log('res.finished : ', res.finished);
//let nickval : any = await db.readRows('users', 'nickname', `nickname = \'${nickname}\'`);
//await db.createRows('test', '(color, odor, taste, quantity)', '(\'meaningless\', \'absent\', \'sadness\', 0)');
console.log('res.finished : ', res.finished);
Piece of Terminal:
res.finished : false
res.finished : false
但是當我取消注釋資料庫查詢時,它變成了這樣:
Piece of index.ts code:
console.log('res.finished : ', res.finished);
//let nickval : any = await db.readRows('users', 'nickname', `nickname = \'${nickname}\'`);
await db.createRows('test', '(color, odor, taste, quantity)', '(\'meaningless\', \'absent\', \'sadness\', 0)');
console.log('res.finished : ', res.finished);
Piece of Terminal:
res.finished : false
Postgres: Rows were created...
res.finished : true
postgres 管理器類中 db.createRows 的代碼如下所示:
public async createRows(table : string, columns: string | string[], values: string | string[]) : Promise<void> {
let createPromise = new Promise<void> ((resolve, reject) => {
this.db.query(`INSERT INTO ${table} ${columns} VALUES ${values};`, (err) => {
if(err) throw err;
console.log('Postgres: Rows were created...');
resolve();
});
});
await createPromise;
}
編輯1: 發生錯誤(從app.post呼叫的此函式,昵稱,電子郵件和密碼具有字串值):
async function validationUsers (res : any, email : string = undefined, password : string = undefined, nickname : string = undefined) : Promise<boolean> {
console.log('f:validationUsers email : ', email);
console.log('f:validationUsers password : ', password);
console.log('f:validationUsers : nickname', nickname);
//validation: nickname and email
if(nickname) {
console.log('res.finished : ', res.finished);
//let nickval : any = await db.readRows('users', 'nickname', `nickname = \'${nickname}\'`);
await db.createRows('test', '(color, odor, taste, quantity)', '(\'meaningless\', \'absent\', \'sadness\', 0)');
console.log('res.finished : ', res.finished);
/* if(nickval[0] !== undefined) {
console.log('frofkofro');
res.status(410).send('Nickname already exists');
res.end();
return false;
} */
}
//validation: email
if(email) {
let emailval : any = await db.readRows('users', 'email', `email = \'${email}\'`);
console.log('f:validationUsers if(email) emailval[0] : ', emailval[0]);
if(emailval[0] !== undefined) {
console.log("?00");
res.send('Email already exists');
res.end();
return false;
}
}
//validation: password
if(password) {
let passwordval = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,100}$/;
if(!password.match(passwordval)) {
console.log('password BAM!!!');
res.status(412).send('Password does not match the criteria'); <-- **THIS STRING**
console.log('password BOOM!!!');
//res.end();
return false;
}
}
console.log('End of f:validationUsers');
return true;
}
編輯 2: pool.query 或從 PostgreSQL 的“pg”庫到資料庫的池連接是否有問題?或者可能是 ts-node 編譯器的問題?
所以,我真的不明白發生了什么。我不知道它是否重要,但我使用 ts-node 來編譯和渲染打字稿
編輯 3: 好的,所以我開始使用相同的 5000 埠在新的 ts 檔案新服務器中運行:
app1.get('/db', async (req : any, res : any) => {
console.log('res.finished : ', res.finished);
await db1.createRows('test', '(color, odor, taste, quantity)', '(\'meaningless\', \'absent\', \'sadness\', 0)');
console.log('res.finished : ', res.finished);
res.status(200).send('All is fine this is send');
res.end();
});
并導致控制臺:
Connected to database as pool successfully...
Server started on port 5000
res.finished : false
Postgres: Rows were created...
res.finished : false
POSTMAN 收到 res.send()。嗚嗚嗚??????
uj5u.com熱心網友回復:
當您的 PostgreSQL代碼使用res.send().
我假設這res.send()部分在 PostgreSQL 管理器中,它看起來像一個經過測驗的真實庫 - 那么發生了什么讓它向一個查詢發送兩個答案?
我沒有使用 Typescript 和 pSQL 的經驗,但我使用過 pSQL 并記得幾年前遇到過同樣的問題。
PostgreSQL 支持(我想它仍然支持)多種查詢模式,例如UPDATE b SET a=2 WHERE c; SELECT a FROM b. 這是兩個陳述,也是某些漏洞利用甚至可以起作用的原因。
而且,就像它發生在我身上一樣,即使第二個長度為零并且顯然甚至不是查詢,在您的代碼中
`INSERT INTO ${table} ${columns} VALUES ${values};`
您的 PostgreSQL 經理可能會認為有兩個陳述句。
所以,試著去掉那個明顯無害的';' 最后,看看它是否解決了問題。我沒有使用你的圖書館,但對我來說,它做到了。
uj5u.com熱心網友回復:
我會說錯誤來自這里:
res.send('Email already exists');
res.end();
確實,如果您節點的檔案顯示為:
res.end() 函式用于結束回應程序。這個方法其實來自Node核心,具體來說就是HTTP.ServerResponse的response.end()方法。用于在沒有任何資料的情況下快速結束回應。
鑒于您已經回復了'Email already exists'express.js,您會收到錯誤訊息Cannot set headers after they are sent to the client(這僅表示您已經發送了回復)
我認為只需洗掉即可res.end();解決您的問題。
uj5u.com熱心網友回復:
好吧,這真的很奇怪和奇怪。我有中間件功能 app.use 它看起來像這樣:
app.use(async function (req : any, res : any, next : any) {
console.log(smthng);
get('header') stuff;
if (cond) {
// this is not executed because condition was false in all my situation
} else {
// this is executed in all cases of this thread
req.name = undefined;
next();
}
next()
})
如您所見,中間件函式的末尾是 next()。所以,我洗掉了 JUST THIS NEXT 并且:
Terminal:
res.finished : false
Postgres: Rows were read...
[]
res.finished : false
res.finished : false
Postgres: Rows were read...
[]
f:validationUsers if(email) emailval[0] : undefined
res.finished : false
password BAM!!!
password BOOM!!!
我不知道發生了什么,我認為這是編譯器下的深海精神分裂癥超流體流動,db promise、中間件和 res.send() 之間存在一些交叉點
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/512439.html
上一篇:等待函式創建修改后的陣列
下一篇:無法顯示服務器/用戶資訊
