簡體   English   中英

“res.end”不是“res.on('end', () =>” (express.js) 中的 function

[英]“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 /apires變量在那里不可用。

此外,在 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.setHeaderres.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.

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