decodeURIComponent 报错:URI malformed 的问题记录

文章讲述了在生产环境中遇到的404错误,源于使用decodeURIComponent时处理包含汉字转义字符的长文本。作者发现decodeURIComponent对特殊字符有特定要求,通过encodeContent函数进行转义后解决了问题,提醒开发者在处理用户输入数据时要谨慎编码。
摘要由CSDN通过智能技术生成

今日发现生产环境里部署的日志报错,报404,提示程序错误

这是一个使用koa搭建的nodejs接口服务,接收一个长文本解析成发货省市区地址信息

片段代码如下:

router.post("/resolution", async (ctx, next) => {
    const queryInfo = decodeURIComponent(ctx.request.body['Content']);
    //………………
});

报错日志是这么写的

server error URIError: URI malformed
    at decodeURIComponent (<anonymous>)
    at D:\workspace\project\routes\address.js:7:23
    at dispatch (D:\workspace\project\node_modules\koa-compose\index.js:44:32)
    at next (D:\workspace\project\node_modules\koa-compose\index.js:45:18)
    at D:\workspace\project\node_modules\koa-router\lib\router.js:346:16
    at dispatch (D:\workspace\project\node_modules\koa-compose\index.js:44:32)
    at D:\workspace\project\node_modules\koa-compose\index.js:36:12
    at dispatch (D:\workspace\project\node_modules\koa-router\lib\router.js:351:31)
    at dispatch (D:\workspace\project\node_modules\koa\node_modules\koa-compose\index.js:42:32)
    at dispatch (D:\workspace\project\node_modules\koa-router\lib\router.js:332:32)
    at dispatch (D:\workspace\project\node_modules\koa\node_modules\koa-compose\index.js:42:32)
    at dispatch (D:\workspace\project\node_modules\koa-router\lib\router.js:332:32)
    at dispatch (D:\workspace\project\node_modules\koa\node_modules\koa-compose\index.js:42:32)
    at D:\workspace\project\app.js:45:9
    at dispatch (D:\workspace\project\node_modules\koa\node_modules\koa-compose\index.js:42:32)
    at views (D:\workspace\project\node_modules\koa-views\src\index.js:91:12) {
  request: {
    method: 'POST',
    url: '/address/resolution',
    header: {
      'user-agent': '……………………',
      'content-type': 'application/json',
      accept: '*/*',
      host: '……………………',
      'accept-encoding': 'gzip, deflate, br',
      connection: 'keep-alive',
      'content-length': '270'
    }
  },
  response: {
    status: 404,
    message: 'Not Found',
    header: [Object: null prototype] {
      vary: 'Origin',
      'access-control-allow-origin': '*',
      'access-control-expose-headers': 'WWW-Authenticate,Server-Authorization'
    }
  },
  app: { subdomainOffset: 2, proxy: false, env: 'development' },
  originalUrl: '/address/resolution',
  req: '<original node req>',
  res: '<original node res>',
  socket: '<original node socket>'
}

上来就被误导了,前几天刚解决掉 content-type的问题,以为调用端有代码没改,检查了一圈,发现content的内容是:

山东省青岛市黄岛区    龙山街道王子山路迢兴科技5号仓库,原装鞋盒外禁缠胶带!退换在原鞋盒外套快递加固箱退回,损坏影响二次销售按订单金额40%赔付或严重拒收,拒收到付件和百世!

用 decodeURIComponent 在浏览器控制台试了一下这个,报一样的错:URI malformed

我以为是接口404是咋了呢?立马定位到这句话里面的那个40%

经过考察一些资料得知,原来decodeURIComponent  不是像普通字符串处理函数一下随便用的,里面会对一些传参字符串做转译,如:%、&、#、=

而这个%是汉字转译的开头,就发生了这个错误

那既然知道这个问题,解决办法就简单了,转成能让他认的字符不就好了?

写一个转换方法,对这四个字符做转换,然后再使用

function encodeContent(key) {
    const encodeArr = [{
        code: '%',
        encode: '%25'
    }, {
        code: '?',
        encode: '%3F'
    }, {
        code: '#',
        encode: '%23'
    }, {
        code: '&',
        encode: '%26'
    }, {
        code: '=',
        encode: '%3D'
    }];
    return key.replace(/[%?#&=]/g, ($, index, str) => {
        for (const k of encodeArr) {
            if (k.code === $) {
                return k.encode;
            }
        }
    });
}

// 然后这样,就行啦!
const queryInfo = decodeURIComponent(encodeContent(ctx.request.body['Content']));

总结,平时看起来没问题的函数,在实际应用中不知道会传进来什么东西,这个decodeURIComponent以后用之前要考虑数据进来的途径,需谨慎😓

处理接收数据的时候,要注意将数据转换下,避免导致函数返回异常

  • 23
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值