[英]“res.end” is not a function in “res.on('end', () =>” (express.js)
我對如何在我的網頁上顯示從 api 獲得的 json 結果感到困惑
我正在使用 express.js + node.js 和 Bing API
這是我的代碼
const https = require('https');
const express = require("express");
const app = express();
var port = 8000;
const SUBSCRIPTION_KEY = 'xxxxxxxxxxxxxxxxxxxxx'
if (!SUBSCRIPTION_KEY) {
throw new Error('error no keys')
}
app.use(express.static("example.com"));
function bingWebSearch(query) {
https.get({
hostname: 'api.cognitive.microsoft.com',
path: '/bing/v7.0/search?q=' + encodeURIComponent(query),
headers: { 'Ocp-Apim-Subscription-Key': SUBSCRIPTION_KEY },
}, res => {
let body = ''
res.on('data', part => body += part)
res.on('end', () => {
// yes this could work and print out result json at my terminal
console.dir(JSON.parse(body), { colors: false, depth: null })
// but why this can not work with error msg I posted below
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ a: 1 }));
// I cant even output this on my webpage, and actually I want to print of course the result json
})
res.on('error', e => {
console.log('Error: ' + e.message)
throw e
})
})
}
app.get("/api", (req, res) => {
const searchString = `${req.query.q}`;
bingWebSearch(searchString);
});
app.listen(port, () => console.log('Your app is ready! Navigate to: http://localhost:' + port + '/.'));
和錯誤信息在這里
/var/www/bing-web-search.js:27
res.setHeader('Content-Type', 'application/json');
^
/var/www/bing-web-search.js:28
res.end(JSON.stringify({ a: 1 }));
^
TypeError: res.setHeader is not a function
TypeError: res.end is not a function
at IncomingMessage.res.on (/var/www/bing-web-search.js:31:11)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
ps 如果我將第 27,28 行移到 app.get
app.get("/api", (req, res) => {
const searchString = `${req.query.q}`;
bingWebSearch(searchString);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ a: 1 }));
});
他們很好地出現在我的網頁上
所以我只是不知道如何讓我的結果也顯示在我的網頁上
任何提示或幫助將不勝感激,謝謝!
這是關於編程的一個非常基本的概念,稱為 scope。 而且您實際上非常接近解決方案。 您可以在此處閱讀 Javascript 中有關 scope 的信息。
在GET /api
的調用中,另一個 function bingWebSearch(searchString)
被調用。 bingWebSearch
有自己的 scope。 所以GET /api
的res
變量在那里不可用。
此外,在 bingWebSearch 中,您發出https.get
請求,並且您還命名了返回值res
。
一種解決方案是將GET /api
的 res 變量作為參數傳遞:
bingWebSearch(searchString, res)
但是當然你需要重命名https.get
的返回值。 你可以稱之為response
。
看起來像這樣:
app.get("/api", (req, res) => {
bingWebSearch(searchString, res);
});
function bingWebSearch(query, res) {
https.get({
...
}, response => {
let body = ''
response.on('data', part => body += part)
response.on('end', () => {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ a: 1 }));
}
}
}
另一種解決方案是從 bingWebSearch 實際return
JSON 字符串,然后在app.get("/api")
中調用res.setHeader
和res.end
。
我想我更喜歡那個,因為我認為它更具可讀性。 但是你必須考慮到https.get
被稱為異步。 因此,如果您嘗試僅返回其結果,則還沒有結果。 但這本身就是一個主題,而不是在您問題的 scope 范圍內。 昆汀的回答對此有一些暗示。
您有兩個名為res
的不同變量。 他們有完全不同的價值觀。
這里定義的res
:
app.get("/api", (req, res) => {
... 是 object 代表您將從 Express發送到客戶端的響應。
這里定義的res
:
}, res => {
… 是 object 代表您從 Bing收到的響應。
您正在嘗試將 Bing 的響應視為您發送給客戶端的響應。
既然不是,那就失敗了。 它以您所看到的特定方式失敗,因為這兩個對象的 API 不同。
您需要將數據從bingWebSearch(searchString);
響應與 Express 響應 object 在同一位置。 為兩個res
變量使用不同的變量名也不是一個壞主意,它會使代碼不那么混亂。
由於您使用的是https.get
,因此您可以通過傳入回調 function 來完成此操作,該回調會關閉 Express res
變量,但將其包裝在 ZB321DE3BDC299EC807E9F795DDEEBZ 中可能會更容易。 將https.get
替換為默認使用 Promise 的 API 會更容易(例如 Axios)。
進一步閱讀: 如何從異步調用返回響應?
const https = require('https');
const express = require("express");
const app = express();
var port = 8000;
const SUBSCRIPTION_KEY = 'xxxxxxxxxxxxxxxxxxxxx'
if (!SUBSCRIPTION_KEY) {
throw new Error('error no keys')
}
app.use(express.static("example.com"));
function bingWebSearch(query) {
https.get({
hostname: 'api.cognitive.microsoft.com',
path: '/bing/v7.0/search?q=' + encodeURIComponent(query),
headers: { 'Ocp-Apim-Subscription-Key': SUBSCRIPTION_KEY },
}, (req, res) => {
let body = ''
res.on('data', part => body += part)
res.on('end', () => {
// yes this could work and print out result json at my terminal
console.dir(JSON.parse(body), { colors: false, depth: null })
// but why this can not work with error msg I posted below
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ a: 1 }));
// I cant even output this on my webpage, and actually I want to print of course the result json
})
res.on('error', e => {
console.log('Error: ' + e.message)
throw e
})
})
}
app.get("/api", (req, res) => {
const searchString = `${req.query.q}`;
bingWebSearch(searchString);
});
app.listen(port, () => console.log('Your app is ready! Navigate to: http://localhost:' + port + '/.'));
express 在 function 的第二個參數中返回響應,而不是在第一個參數中。 所以我在第 18 行更正了它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.