url跳转时特殊字符转义

786 阅读2分钟

问题

事情要从最近接手的小程序项目说起。。。
线上一个展示股票观点详情页面打开无数据展示,非常离谱,抓紧排错。 首先不是所有的页面都无数据,而是部分观点详情无数据,定位到传递到详情页的数据:
pageA中跳转到pageB,并传递了data

wx.navigateTo({
    url: '/pages/B?data=' + JSON.stringify(obj)
})

pageB中接收data

JSON.parse(data)

乍一看好像没什么问题,但是报错了,因为JSON.parse解析不出来data

image.png

问题就出在传递的obj中包含了用户输入的内容,而用户输入的内容中包含了一些特殊字符,对于路由接口wx.navigateTo

为了避免不可预知的请求,我们应该给任何用户输入的作为url部分的内容需要用encodeURIComponent 进行转义。

如果不进行转义,将得到错误的内容。

解决

方案1

传递的时候使用encodeURIComponent进行编码,接收的时候使用decodeURIComponent解码一次。具体用法戳MDN

encodeURIComponent(JSON.stringify(obj))

方案2(推荐)

方案1虽然比较通用,但是查看wx.navigateTo文档,发现它提供了一个success回调,可以与被打开的页面pageB通信,通信方式更加灵活,不需要在url中传递参数。

image.png pageA

wx.navigateTo({
  url:' /pages/B', 
  success: function (res){
  //通过 eventchannel 向被打开页面传送数据
    res.eventChannel.emit('acceptDataFromOpenerPage', obj)
  }
})

pageB

const eventChannel = this.getopenerEventChannel() 
eventChannel.on('acceptDataFromOpenerPage', function (data){
  console.log(data)
}

补充

encodeURI, encodeURIComponent的区别和使用场景?

参考文章:escape,encodeURI,encodeURIComponent有什么区别?

区别

首先它们都是编码url的常用方式,不同之处就在于它们编码的字符范围。
encodeURI不会对下列字符编码 ASCII字母 数字 ~!@#$&*()=:/,;?+'
encodeURIComponent方法不会对下列字符编码 ASCII字母 数字 ~!*()'
所以encodeURIComponentencodeURI编码的范围更大,举例来说:

encodeURIComponent会把 http:// 编码成 http%3A%2F%2F 而encodeURI却不会。

使用场景

  1. 如果需要编码整个url,然后需要使用这个url,那么用encodeURI
    比如:
encodeURI("http://www.juejin.cn/editor/some other thing");

将会被编码成:

"http://www.juejin.cn/editor/some%20other%20thing";

其中,空格被编码成了%20。但是如果你用了encodeURIComponent,那么结果变为:

"http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2Fsome%20other%20thing"

连 "/" 都被编码了,整个url已经没法用了。

  1. 当需要编码url中的参数的时候,使用encodeURIComponent
var param = "http://www.juejin.cn/editor/"; //param为参数
param = encodeURIComponent(param);
var url = "http://www.juejin.cn/editor?next=" + param;
console.log(url) 
//"http://www.juejin.cn/editor?next=http%3A%2F%2Fwww.juejin.cn%2Feditor%2F"