Nodejs express如何设置route使得QueryString里面的+号不被转成空格?

Nodejs express如何设置route使得QueryString里面的+号不被转成空格?

比如我的一个原始的请求的URL为:

http://192.168.1.150:3000/messenger?between=TxPhdW828e7GF63pw1/Uve6kYFsv5zrSfnDP6wj67t4WpG7sSuEwSd8ugyFD8r1z1CJkPpqVxuYqEV3xoLypUOqg0IMVy+lqylVx9+wvikw=

但是到了express里面默认取到的between的值就为:

TxPhdW828e7GF63pw1/Uve6kYFsv5zrSfnDP6wj67t4WpG7sSuEwSd8ugyFD8r1z1CJkPpqVxuYqEV3xoLypUOqg0IMVy lqylVx9 wvikw=

这就刚好是将+号给替换成了空格啊。

如何设置能够让express获取到的QueryString就是原始的QueryString呢?


5 回复

要在Express中处理Query String中的+符号,使其不被转换为空格,可以通过自定义中间件来解析查询字符串。默认情况下,Express使用query中间件来解析查询字符串,该中间件会自动将+符号转换为空格。你可以通过自定义解析逻辑来避免这种行为。

以下是一个示例代码,展示如何创建一个自定义中间件来解析查询字符串,并保留原始的+符号:

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

// 自定义中间件解析查询字符串
app.use((req, res, next) => {
    // 解析原始查询字符串
    const queryString = req.originalUrl.split('?')[1];
    if (queryString) {
        // 使用decodeURIComponent来解析查询字符串
        const queryObject = {};
        const pairs = queryString.split('&');

        for (let pair of pairs) {
            let [key, value] = pair.split('=');
            key = decodeURIComponent(key);
            value = decodeURIComponent(value.replace(/\+/g, '%2B'));
            queryObject[key] = value;
        }

        // 将解析后的对象赋值给req.query
        req.query = queryObject;
    }
    next();
});

// 示例路由
app.get('/messenger', (req, res) => {
    console.log(req.query.between); // 输出原始的值,包括 + 号
    res.send('Request processed');
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 自定义中间件

    • app.use 中间件用于解析查询字符串。
    • req.originalUrl 包含完整的请求URL,我们从中提取出查询字符串部分。
    • 使用 split('&') 方法将查询字符串拆分成键值对数组。
    • 对每个键值对进行解码,并将 + 符号替换为 %2B,以保留其原始形式。
    • 将解析后的对象赋值给 req.query
  2. 路由处理

    • 在路由处理函数中,可以直接访问 req.query.between 并获取包含原始 + 符号的值。

这样,你就可以确保Express在处理查询字符串时不会将 + 符号转换为空格。


自己改REQ的函数吧

用encodeURIComponent编码再传过来试试

console.log(encodeURIComponent(‘TxPhdW828e7GF63pw1/Uve6kYFsv5zrSfnDP6wj67t4WpG7sSuEwSd8ugyFD8r1z1CJkPpqVxuYqEV3xoLypUOqg0IMVy+lqylVx9+wvikw=’));

TxPhdW828e7GF63pw1%2FUve6kYFsv5zrSfnDP6wj67t4WpG7sSuEwSd8ugyFD8r1z1CJkPpqVxuYqEV3xoLypUOqg0IMVy%2BlqylVx9%2Bwvikw%3D

console.log(unescape(‘TxPhdW828e7GF63pw1%2FUve6kYFsv5zrSfnDP6wj67t4WpG7sSuEwSd8ugyFD8r1z1CJkPpqVxuYqEV3xoLypUOqg0IMVy%2BlqylVx9%2Bwvikw%3D’));

TxPhdW828e7GF63pw1/Uve6kYFsv5zrSfnDP6wj67t4WpG7sSuEwSd8ugyFD8r1z1CJkPpqVxuYqEV3xoLypUOqg0IMVy+lqylVx9+wvikw=

请求过来的URL是你自己弄的还是别人传过来的? 你可以改变请求过来的参数吗? 一般来说,都是请求过来的url自己需要做好url encode的。 一个url请求,自己不做url encode那肯定是不对的。

为了防止Express在处理查询字符串时将+号转换为空格,可以通过修改查询字符串的解析方式来实现。Express 使用 qs 库来解析查询字符串,默认情况下它会将 + 解析为空格。

你可以通过自定义中间件或配置来改变这种行为。下面是一种可能的解决方案:

示例代码

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

// 自定义解析查询字符串的方式
app.use((req, res, next) => {
    // 使用qs库并配置为不解析+为' '
    const qs = require('qs');
    req.query = qs.parse(req._parsedUrl.query, { delimiter: '&', decodeURIComponent: false });
    next();
});

app.get('/messenger', (req, res) => {
    console.log(req.query.between);
    res.send('Request processed');
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 引入依赖:首先引入Express模块。
  2. 自定义中间件:创建一个中间件,在该中间件中使用qs库(默认情况下Express使用qs库)解析查询字符串,并配置其选项以避免将+解析为空格。
  3. 注册路由:定义一个GET路由来处理/messenger路径上的请求。
  4. 启动服务器:最后,启动Express服务器监听3000端口。

注意事项

  • 上述代码中的decodeURIComponent: false参数是为了避免自动解码URI组件,从而保留+符号。如果你希望保留原始的编码,可以进一步调整配置。
  • 确保你的项目中已经安装了qs模块,如果还没有安装,可以通过npm install qs命令进行安装。

这样设置后,+号就不会被转换为空格了。

回到顶部