【问题标题】:checkbox array returns the last checked value in nodejs, not whole array复选框数组返回nodejs中的最后一个检查值,而不是整个数组
【发布时间】:2021-04-11 12:43:11
【问题描述】:

我正在尝试通过 req.body 复选框中的选中值。如果我只检查一个没有问题,并且在 req.body 上有一个具有该值的对象。如果我检查不止一个,那么它会返回我检查的最后一个。我正在使用 express ejs 和 express.json() 作为正文解析器。

这是我的应用程序文件中我配置 express.json() 的部分

const express = require("express");
const path = require("path");
const rateLimit = require("express-rate-limit");
const helmet = require("helmet");
const mongoSanitize = require("express-mongo-sanitize");
const xss = require("xss-clean");
const hpp = require("hpp");
const cookieParser = require("cookie-parser");

const throwsAnError = require("./utils/throwsAnError");
const checkAuth = require('./middleware/check-auth');

const app = express();

if(process.env.NODE_ENV !== "test"){
    const limiter = rateLimit({
        max: 100,
        windowMs: 60 * 60 * 1000,
        message: "Too many request, please try again in an hour"
    });
    
    app.use("/api", limiter);
}

app.set("view engine", "ejs")
app.set("views", path.join(__dirname, "views"))

app.use(express.static(path.join(__dirname, "public")));
app.use(cookieParser());
app.use(helmet());
// For security reasons we accept body up to 10kb
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ extended: false }));
// Data sanitization (Cleaning the income data from malicious code)
// NoSQL data injection
app.use(mongoSanitize());

// Data sanitization against XSS
app.use(xss());

//Preventing HTTP parameter poloution
app.use(hpp());

路由器是这样的:

router.get("/offers/masoutis-offers", authController.isLoggedIn, viewController.masoutisOffers);
router.post("/offers/masoutis-offers", authController.isLoggedIn, viewController.masoutisOffers);

控制器是这样的:

exports.masoutisOffers = async function(req, res) {
    console.log(req.body);
    const products = await getOffers(req);

    res.status(200).render("displayProducts", {
        title: "Επιλεγμένες Προσφορές",
        products
    });
}

async function getOffers(req) {
    const page = parseInt(req.query.page || 1); 
    const sort = req.query.sort || "discountPrice";
    const itemsPerPage = 10;
    const totalProducts = await Offers.countDocuments();
    const products = await Offers.find()
        .skip((page - 1) * itemsPerPage)
        .limit(itemsPerPage) 
        .sort(sort);
    return {
        products,
        sort,
        currentPage: page,
        hasNextPage: itemsPerPage * page < totalProducts,
        hasPreviousPage: page > 1,
        nextPage: page + 1,
        previousPage: page - 1,
        lastPage: Math.ceil(totalProducts / itemsPerPage)
    }
}

我使用的测试表格是这样的:

<form action="" method="post">
        <input type="checkbox" id="hobby" name="stuhobbies" value="sing"/> &nbsp;&nbsp;<strong>Sing</strong>&nbsp;&nbsp;
        <input type="checkbox" id="hobby" name="stuhobbies" value="guitarplay"/>&nbsp;&nbsp;<strong>GuitarPlay</strong>&nbsp;&nbsp;
        <input type="checkbox" id="hobby" name="stuhobbies" value="cricket"/>&nbsp;&nbsp;<strong>Cricket</strong>&nbsp;&nbsp;
        <input type="checkbox" id="hobby" name="stuhobbies" value="football"/>&nbsp;&nbsp;<strong>Football</strong>&nbsp;&nbsp;
        <button type="submit">submit</button>
      </form>

例如,如果我检查所有值,作为来自 console.log(req.body) 的返回,我会收到 { stuhobbies: 'football' } 而不是所有值的数组

【问题讨论】:

标签: node.js arrays forms express checkbox


【解决方案1】:

我所做但无法获取数组的是我安装了一个名为 hpp https://www.npmjs.com/package/hpp 的包。它从 req.body 中删除任何数组并只放入数组中的最后一个值。它有一个白名单选项,这就是我解决它的方式。

【讨论】:

    【解决方案2】:

    使用快递的extended URL-encoded body parsing,像这样

    app.use(express.urlencoded({extended: true}));
    

    或者,在旧版本的 express 中,通过 body-parser package 像这样

    const bodyParser = require('body-parser')
    ...
    app.use(bodyParser.urlencoded({ extended: true}))
    

    然后你可以把这种东西放在你的复选框html中。

    <form action="" method="post">
       <input type="checkbox" id="checkboxsing"    name="voice[]" value="sing"/> Sing
       <input type="checkbox" id="checkboxshout"   name="voice[]" value="shout"/> Shout
       <input type="checkbox" id="checkboxwhisper" name="voice[]" value="whisper"/> Whisper
       <input type="checkbox" id="checkboxmumble"  name="voice[]" value="mumble"/> Mumble
       <button type="submit">submit</button>
    </form>
    

    您将在 .post() 处理程序的 req.body 对象中看到这一点。

    {
     "voice": [
          "sing",
          "shout"
        ],
    }
    

    请注意,我的示例中每个复选框的 id 属性都不同。使用相同的 id 创建两个 DOM 对象(&lt;div&gt;&lt;input&gt; 等)是无效的 HTML。浏览器不会抱怨,但它会阻止您这样做来标记复选框。

    <form action="" method="post">
       <input type="checkbox" id="checkboxsing"    name="voice[]" value="sing"/>
       <label for="checkboxsing">Sing</label>
       <input type="checkbox" id="checkboxshout"   name="voice[]" value="shout"/>    
       <label for="checkboxshout">Shout</label>
       <input type="checkbox" id="checkboxwhisper" name="voice[]" value="whisper"/>    
       <label for="checkboxwhisper">Whisper</label>
       <input type="checkbox" id="checkboxmumble"  name="voice[]" value="mumble"/>    
       <label for="checkboxmumble">Mumble</label>
       <button type="submit">submit</button>
    </form>
    

    【讨论】:

      猜你喜欢
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 2021-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多