【问题标题】:node js console and endpoint returning object but cannot fetch as json object节点 js 控制台和端点返回对象但不能作为 json 对象获取
【发布时间】:2020-02-24 14:18:41
【问题描述】:

我正在为一个项目和在线课程使用 NLP 情绪分析 API。我想我已经接近了,但我无法完成最后一步。目前,当我发送要由 API 调用分析的 URL 时,我在服务器控制台中获取返回的对象,然后将数据发送到路由/sentiment。然后我有一个函数,我试图从 /sentiment 获取数据并更新页面以显示结果。 #hen 我尝试从 /sentiment 获取数据我得到一个空对象,并且我的页面使用未定义更新。当我转到 /sentiment 时,我可以看到所有数据,但提取不起作用。我认为这些是我的代码的相关部分:

index.js(服务器端):

var path = require('path');
const express = require('express');
const mockAPIResponse = require('./mockAPI.js');
const dotenv = require('dotenv');
const bodyParser = require('body-parser');

const app = express()
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());

app.use(express.static('dist'))

dotenv.config();
console.log(`Your API key is ${process.env.API_ID}`);

console.log(__dirname)

projectData = {};

url = {};

const AYLIENTextAPI = require('aylien_textapi');

let textapi = new AYLIENTextAPI({
    application_id: process.env.API_ID,
    application_key: process.env.API_KEY,
})


let apiCall = async (url) => {
    textapi.sentiment({
        'url': url
    }, function(error, response) {
        if (error === null) {
            JSON.stringify(response);
            projectData = response;
            console.log(projectData);
        }else{
            console.log(error)
        }
    })
};

app.route('/')
    .get(function (req, res) {
        console.log(process.env);
        res.sendFile('dist/index.html', { root: __dirname + '/,'})
    })
    .post(getSentiment);

function getSentiment(req, res){
    console.log(req.body);
    projectData = req.body;
    console.log(projectData);
    res.status(200).send(projectData);
};

const port = 8000;

// designates what port the app will listen to for incoming requests
app.listen(port, function () {
    console.log(`Example app listening on ${port}`)
})

app.get('/sentiment', getData);

function getData(req, res){
    JSON.stringify({projectData});
    res.status(200).send(projectData)
    console.log(projectData)
};

app.post('/postURL', getURL);

function getURL(req, res){
    console.log(req.body);
    url = req.body.data;
    console.log(url)
    apiCall(url)
}

formHandler.js:


import { postURL } from "./postURL"
import { updateUI } from "./updateUI"

function handleSubmit(event) {
    event.preventDefault()

    // check what text was put into the form field
    let url = document.getElementById('URL').value
    postURL('/postURL', url)
    updateUI();
};

export { handleSubmit }

更新UI.js:

const updateUI = async () =>{
    const res = await fetch('/sentiment');
    try {
        const allData = await res.json();
        console.log(allData)
        document.getElementById("polarity").innerHTML = allData.polarity;
        document.getElementById("polarityConfidence").innerHTML = allData.polarity_confidence;
        document.getElementById("subjectivity").innerHTML = allData.subjectivity;
        document.getElementById("subjectivityConfidence").innerHTML = allData.subjectivity_confidence;
        return allData
    } catch(error) {
        console.log(error)
    }
};

export { updateUI }

我不知道为什么我在服务器端和 /sentiment 看到所有数据,但是当我尝试在 updateUI 函数中获取它时只得到一个空对象。任何帮助都会非常非常感谢。

非常感谢, 迈克尔

【问题讨论】:

  • 这什么也没做 -> JSON.stringify({projectData}); 试试 -> res.status(200).json(projectData)

标签: javascript node.js express


【解决方案1】:

您需要提供到服务器的完整路径,例如

const res = await fetch('http://localhost:8000/sentiment');

或者尝试移动

app.get('/sentiment', getData);

以上

app.route('/')

更新

const allData = await res.json(); // problem is here

试试

 console.log(res.data); // here you will see what you are getting.
 const allData = await res.data; // You might will be having the response here


你这可能会有所帮助。
const updateUI = async () =>{
    const res = await fetch('/sentiment');
    try {
        const allData = res.data; // here
        console.log(allData)
        document.getElementById("polarity").innerHTML = allData.polarity;
        document.getElementById("polarityConfidence").innerHTML = allData.polarity_confidence;
        document.getElementById("subjectivity").innerHTML = allData.subjectivity;
        document.getElementById("subjectivityConfidence").innerHTML = allData.subjectivity_confidence;
        return allData
    } catch(error) {
        console.log(error)
    }
};

export { updateUI }

【讨论】:

  • 这些解决方案都不起作用。还有其他想法吗?
  • @MichaelWycklendt 运行 console.log(projectData) 后,您在控制台中得到了什么?在 getData 函数中
  • 我将所有数据打包在 {}
  • 我改变了 const allData = await res.json();到 const allData = await JSON.parse(res.data) 和 const allData = JSON.parse(res.data) 并得到错误 SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse ()。知道为什么吗?
  • 当我添加 console.log(res) 我得到 Response {type: "basic", url: "localhost:8000/sentiment", redirected: false, status: 200, ok: true, ...} in控制台
【解决方案2】:

JSON.stringify + res.send = 内容类型“文本/html”

您的客户端应用无法将其反序列化为 JSON。 您的问题是您正在 JSON.stringify-ing 它并通过 res.send 从服务器发送它。

此组合设置了错误的 Content-Type 标头。

阅读 res.send 的 Express API 文档:

当参数为String时,该方法将Content-Type设置为“text/html”:

所以您可以在浏览器中看到它,因为浏览器正在呈现文本,但客户端应用程序无法使用 res.json() 反序列化它,因为内容类型未从服务器正确设置。

function getData(req, res){
    JSON.stringify({projectData});
    res.status(200).send(projectData) <- "text/html"
    console.log(projectData)
};

需要设置为application/json

这是你需要做的事情

  1. 将端点更改为sendJson
  2. 不要JSON.stringify它。发送对象并让 Express 对其进行序列化。
function getData(req, res){
    // JSON.stringify({projectData}); <- don't stringify it
    res.sendJson(projectData) // <- use sendJSON
    console.log(projectData)
};

阅读 res.json 的 Express API 文档:

发送 JSON 响应。此方法发送一个响应(具有正确的内容类型),该响应是使用 JSON.stringify() 转换为 JSON 字符串的参数。

【讨论】:

  • 他没有将JSON.stringify({projectData}) 分配给某事,因此可能没有帮助:-)。
  • 看看他的服务器中的getData 方法。他正在对 JSON 进行字符串化,然后将字符串化的 json 作为明文发送。在客户端使用res.json()。我的假设是他可以在他的浏览器中看到它,但是 json 序列化不适用于客户端应用程序中的 res.json(),可能是因为内容类型标头。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多