【问题标题】:Express JS sends undefined JSON variables to clientExpress JS 向客户端发送未定义的 JSON 变量
【发布时间】:2020-10-27 19:42:47
【问题描述】:

我正在学习 Express JS 并练习安全性。我已将一些优惠券代码逻辑移至服务器,以使其更安全。这意味着我向服务器发送优惠券代码,它会检查它是否是有效代码,然后返回带有消息和获胜指示符的 JSON 对象(1 代表获胜,0 代表失败)。

我的问题是我无法弄清楚如何从响应中获取客户端上的消息和获胜指示器。总是undefined

这是客户:


window.addEventListener("load", () => {
    const nameInput = document.getElementById("name");
    const couponCodeInput = document.getElementById("coupon-code");
    const button = document.getElementById("button");
    const nowinElem = document.getElementById("no-win");
    const winElem = document.getElementById("you-won");

    button.addEventListener("click", async e => {
        e.preventDefault();
        winElem.style.display = "none";   //new click of button:
        nowinElem.style.display = "none"; // hide previous messages
        let resp = await fetch('winner', { 
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ name: nameInput.value, code: couponCodeInput.value }) 
        });
        
        if (resp.status !== 200) console.log('Winner report failed');        

        var res = resp.body;

        if(res.win == "1"){
            winElem.style.display = "block";
            winElem.innerText = res.msg;
        } else {
            nowinElem.style.display = "block";
            nowinElem.innerText = res.msg;
       }
            
    })
})

这是服务器:

const express = require('express')
const fs = require('fs')
const app = express()

const html = fs.readFileSync('coupon-client.html');
const js = fs.readFileSync('coupon-client.js');

const winnerCodes = ["123", "secret", "abc321"];

app.get('/', (req, res) => {
    res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"});
    res.end(html);
 })
app.get('/coupon-client.js', (req, res) => {
    res.writeHead(200, {"Content-Type": "application/javascript"});
    res.end(js);
})
app.post('/winner', express.json(), (req, res) => {//use built-in JSON middle-ware
    let jsonObj = req.body //JSON already parsed: { "name": "my name" }
    if(winnerCodes.includes(jsonObj.code)){
        console.log(`Congratulations to ${jsonObj.name}!`);
        console.log("We'll send you a diploma.");
        res.json({msg: 'Congratulations - and thanks!', win: '1'});
    } else {
        console.log(`Condolences to ${jsonObj.name}!`);
        console.log("We'll send you nothing.");
        res.json({msg: 'Sorry, you did not win - but thanks for playing!', win: '0'});
    }
}) 

app.listen(8080, () => console.log('Listening...'))

如上所述,我无法获取 JSON 数据对象来为我提供 win 和 message 变量。我试图做“JSON.parse(resp.body)”,但它给了我一个错误,说“unexpected character at ....”,我读到这意味着身体已经被解析,所以我只是采取现在是尸体。

谁能给我提示或帮助我?

【问题讨论】:

  • 您是否尝试在let jsonObj = req.body 行设置断点并查看req.body

标签: javascript node.js json express


【解决方案1】:

读取Response 对象的方式与您当前使用它的方式不同。
对响应对象使用json() 方法。它将返回一个 Promise,它将来自 JSON 的响应解析为可用数据。

关于Response 对象及其用法。
当前,您正在访问 Response 对象上的 body 属性,该对象继承自 Body mixin。

Body mixin 的 body 只读属性是一个简单的 getter,用于公开正文内容的 ReadableStream。 MDN

因此,您正在访问 ReadableStream 对象并尝试从中读取 win 属性,该属性在流中不存在。

为了解决这个问题,Body mixin 提供了将流转换为可用数据的方法。例如Body.json()Body.text()。这些方法读取流并将正文转换为对象、数组、字符串或数字(当它具有 JSON 结构或单个字符串时),这在您发送 HTML 或只是原始文本时很有用。

这两种方法都返回 Promise,您必须在其中等待结果准备好使用。

let resp = await fetch('winner', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: nameInput.value,
    code: couponCodeInput.value
  })
});

if (resp.status !== 200) console.log('Winner report failed');

// Decode body from JSON.
let { win, msg } = await resp.json();

if (win === "1") {
  winElem.style.display = "block";
  winElem.innerText = msg;
} else {
  nowinElem.style.display = "block";
  nowinElem.value = msg;
}

【讨论】:

  • 感谢您的回答,效果很好!您能否详细说明解决方案为何有效以及响应对象是什么样的?
  • @Aletho,我添加了更多关于如何使用 Response 对象的信息,以及更多文档链接供您查看。
猜你喜欢
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 2017-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多