前言

URL对于我们开发人员来讲,应该是非常熟悉了。在对URL进行参数拼接时,我们一般都会直接进行字符串拼接或使用模版字符串,因为这样非常方便,但是我们这样其实会在不知不觉中以不安全的方式编写 URL。

比如,我们通常会这样写:

const url = `https://www.baidu.com
?model=${model}&locale=${locale}?query.text=${text}`

这样确实写起来非常方便,但你可能会在不知不觉中会你的程序带来一些问题。(如上代码就是一段有问题的代码)

如果这篇文章有帮助到你,️关注+点赞️鼓励一下作者,文章公众号首发,关注 前端南玖 第一时间获取最新文章~

常见问题

不正确的分隔符

这种错误可能在新手身上比较常见,但即使是经验老道的程序员也不可能绝对避免这个错误。造成这个错误的罪魁祸首绝大多数是在修改或移动代码之后。例如,你有一个结构正确的 URL,然后将一个片段从一个片段复制到另一个片段,然后错过了参数分隔符的错误排序。

忘记编码

许多时候我们URL上的参数是需要进行编码的,因为URL参数可以是任意类型的文本,包括空格和特殊字符,这会给我们带来一些无法预料的问题。

所以为了避免这种情况,我们往往会这样写:

const url = `https://www.baidu.com
?model=${
encodeURIComponent(model)
}&locale=${
encodeURIComponent(locale)
}&query.text=${
encodeURIComponent(text)
}`

但这样的写法给人的感觉是非常的冗余且不雅观

意外的空白字符

有时候我们为了将一个长 URL 分成多行,我们会不小心在 URL 中包含了换行符和额外的空格,这将导致无法按预期进行抓取。

所以为了正确分解URL字符串,我们通常会这样写:

const url = `https://www.baidu.com`
+ `?model=${
encodeURIComponent(model)
}&locale=${
encodeURIComponent(locale)
}&query.text=${
encodeURIComponent(text)
}`

但这样是我们的代码变得更加混乱以及难以阅读。

难道就没有一种既安全又优雅的方法来编写URL吗?

URL构造函数

既优雅又安全的方法就是使用URL构造函数

URL() 构造函数返回一个新创建的 URL对象,表示由一组参数定义的 URL。

如果给定的基本 URL 或生成的 URL 不是有效的 URL 链接,则会抛出一个TypeError

语法

const url = new URL(url [, base])

参数

  • url

    是一个表示绝对或相对 URL 的 DOMString。如果url 是相对 URL,则会将 base 用作基准 URL。如果 url 是绝对 URL,则无论参数base是否存在,都将被忽略

  • base 可选

    是一个表示基准 URL 的 DOMString,在 url 是相对 URL 时,它才会起效。如果未指定,则默认为 ''

解决

所以上面的URL我们就可以这样来写:

const url = new URL('https://www.baidu.com')

url.searchParams.set('model', model)
url.searchParams.set('locale', locale)
url.searchParams.set('text', text)

这样写就可以为我们解决这些问题:

  • 分隔符总是正确的(?对于第一个参数,以及之后的参数)
  • 所有参数都自动编码
  • 长 URL 跨多行时没有额外空白字符的风险

修改URL

对于我们在不知道当前参数状态下的情况,它也非常适用。

比如:

url += (url.includes('?') ? '&' : '?') + 'foo=bar'

使用URL构造函数我们可以这样写:

// url是一个URL构造函数
url.searchParams.set('foo', 'bar') // 或者是一个字符串
const structuredUrl = new URL(url)
structuredUrl.searchParams.set('foo', 'bar')
url = structuredUrl.toString()

读取URL

现在,我如果想在没有库的情况下从当前 URL 读取查询参数这个由来已久的问题也得到了解决。

const pageParam = new URL(location.href).searchParams.get('page')

const url = new URL(location.href)
const currentPage = Number(url.searchParams.get('page'))
url.searchParams.set('page', String(currentPage + 1))
location.href = url.toString()

这不仅限于浏览器,它也可以在 Node.js 中使用

const http = require('http');

const server = http.createServer((req, res) => {
const url = new URL(req.url, `https://${req.headers.host}`)
});

URL属性

URL 实例支持您已经在浏览器中使用的所有属性,例如 onwindow.location或 anchor 元素,所有这些我们都可以读写

const url = new URL('https://www.baidu.com/a?page=1');

url.protocol // https:
url.host // www.baidu.com
url.pathname // /a
url.search // ?page=1
url.href // https://www.baidu.com/a?page=1
url.origin // https://www.baidu.com
url.searchParams.get('page') // 1

常用URLSearchParams方法

URLSearchParams对象可在URL实例上访问,url.searchParams支持许多方便的方法:

searchParams.has(name)

检查搜索参数是否包含给定名称

url.searchParams.has('page') // true

searchParams.get(name)

获取给定参数的值

url.searchParams.get('page') // '1'

searchParams.getAll(name)

获取为参数提供的所有值。如果你允许同名的多个值,这很方便,例如&page=1&page=2

url.searchParams.getAll('page') // ['1']

searchParams.set(name, value)

设置参数的值

url.searchParams.set('page', '1')

searchParams.append(name, value)

附加一个参数——如果你可能多次支持同一个参数,这很有用,比如&page=1&page=2

url.searchParams.append('page', '2')

searchParams.delete(name)

从 URL 中完全删除一个参数

url.searchParams.delete('page')

兼容性

new URL基本支持所有现代浏览器(除了IE),以及 Node.js。

JavaScript 中更安全的 URL 读写的更多相关文章

  1. 如何在 JavaScript 中更好地使用数组

    使用 Array.includes 替代 Array.indexOf “如果需要在数组中查找某个元素,请使用 Array.indexOf.” 我记得在我学习 JavaScript 的课程中有类似的这么 ...

  2. javascript中函数的3个高级技巧

    × 目录 [1]作用域安全 [2]惰性载入 [3]函数绑定 前面的话 函数对任何一门语言来说都是一个核心的概念,在javascript中更是如此.前面曾以深入理解函数系列的形式介绍了函数的相关内容,本 ...

  3. 详解JavaScript中的Url编码/解码,表单提交中网址编码

    本文主要针对URI编解码的相关问题做了介绍,对Url编码中哪些字符需要编码.为什么需要编码做了详细的说明,并对比分析了Javascript 中和 编解码相关的几对函数escape / unescape ...

  4. Javascript中的url编码与解码(详解)

    摘要 本文主要针对URI编解码的相关问题做了介绍,对url编码中哪些字符需要编码.为什么需要编码做了详细的说明,并对比分析了Javascript中和编解码相关的几对函数escape / unescap ...

  5. java,javascript中的url编码

    真实场景 url示例如下 http://localhost:31956/Login/Auto?Token=e8a67a9f-c062-4964-b703-d79f29c8b64e&Return ...

  6. JavaScript中url 传递参数(特殊字符)解决方法及转码解码的介绍

    有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了.下表中列出了一些URL特殊符号及编码   十六进制值 1. + URL 中+号表示空格 %2B 2. 空 ...

  7. URL地址中中文乱码详解(javascript中encodeURI和decodeURI方法、java.net.URLDecoder.encode、java.net.URLDecoder.decode)

    引言: 在Restful类的服务设计中,经常会碰到需要在URL地址中使用中文作为的参数的情况,这种情况下,一般都需要正确的设置和编码中文字符信息.乱码问题就此产生了,该如何解决呢?且听本文详细道来. ...

  8. Django中如何将javascript中的变量传给位于javascript内的{% url %}中的参数?

    这个问题困扰了我一天,不知道困扰了你多久,希望能帮助你 django 中的url模版使用起来可以说是非常方便的,但是怎么在url模版中传入参数的 {% url "url.index" ...

  9. C#与JavaScript中URL编码解码问题(转)

    混乱的URI编码 JavaScript中编码有三种方法:escape.encodeURI.encodeURIComponent C#中编码主要方法:HttpUtility.UrlEncode.Serv ...

  10. javascript中如何使用js脚本模拟"request"获取url后参数值呢?

    转自:猫猫小屋--js获取url后参数信息 摘要: 下文讲述javascript中使用js代码获取url地址后面的参数值的方法分享,如下所示: 实现思路: 使用正则表达式对参数值进行匹配,获取参数后的 ...

随机推荐

  1. scrapy 解析xml格式的数据

    XMLFeedSpider 主要用于 解析 xml格式的数据 创建一个scrapy 项目文件 scrapy startproject xxx 创建一个spider scrapy genspider - ...

  2. 【jmeter】将“察看结果树”中的数据保存到本地

    操作说明: 1. "察看结果树"页面,[配置]导出项: 2. "察看结果树"页面,[文件名]选框输入导出文件及路径:  3. 点击jmeter[启动]按钮,响应 ...

  3. 关于Docker的一些事--Docker-Compose 升级版本

    起源 近来一直在研究怎么搭建自己的私有网盘,本着虚心耐心,认真求是态度,开始做起了实验,最终种草了Nextcloud这款开源网盘,然而用私人的服务器感觉很卡,故转战到了一个基友的服务器,感觉非常吊! ...

  4. 嵌入式-C语言基础:理解形参和实参的区别

    #include<stdio.h> //实参:函数原型中声明函数后面带的参数 int test(int x)//函数原型 { //函数体 printf("test里面的x地址=% ...

  5. Redis的攻击手法

    目录 Redis概述 Redis未授权 漏洞发现 漏洞验证 Redis写shell 漏洞利用 Redis写公钥 漏洞利用 主从复制RCE 漏洞简介: 漏洞利用 计划任务反弹shell 漏洞利用 Red ...

  6. Go语言核心36讲43-----io包中接口的好处与优势

    上一篇文章中,我主要讲到了io.Reader的扩展接口和实现类型.当然,io代码包中的核心接口不止io.Reader一个. 我们基于它引出的一条主线,只是io包类型体系中的一部分.我们很有必要再从另一 ...

  7. 10、数组a和b各有10个元素。将他们相同的位置元素逐个比较, 如果a中元素大于b中对应元素的次数多于b数组中元素大于a中元素的次数, 则认为a大于b。请统计大于等于小于的次数

    /* 数组a和b各有10个元素.将他们相同的位置元素逐个比较, 如果a中元素大于b中对应元素的次数多于b数组中元素大于a中元素的次数, 则认为a大于b.请统计大于等于小于的次数 */ #include ...

  8. c++ *和& 指针,取内容,别名,取地址

    *前面有类型符时为定义指针 &前面有类型符时为定义引用变量(别名) (int ,float,long,double,char等 ) *p:定义xx类型的指针 int *p 整型指针,char ...

  9. 【Shell案例】【wc记录单词长度、for循环和if、awk文本分析工具】7、打印字母数小于8的单词

    描述写一个 bash脚本以统计一个文本文件 nowcoder.txt中字母数小于8的单词. 示例:假设 nowcoder.txt 内容如下:how they are implemented and a ...

  10. 【知识体系】Kafka文档汇总、组成及架构,配置,常见名词解释,命令行及api操作,官方文档内容,各部分深入,zookeeper和security,监控和运维

    〇.相关资料 1.快速搭建文档: 2.详细讲义 3.在线官方文档:http://kafka.apache.org/documentation/ 4.Kafka知识个人总结 5.KafkaPPT汇报 链 ...