URL构造函数的使用

287 阅读4分钟

URL接口的了解(引用mdn上的说法)

**URL**接口用于解析,构造,规范化和编码 URLs。 它通过提供允许您轻松阅读和修改 URL 组件的属性来工作。 通常,通过在调用 URL 的构造函数时将 URL 指定为字符串或提供相对 URL 和基本 URL 来创建新的 URL 对象。 然后,您可以轻松读取 URL 的已解析组成部分或对 URL 进行更改。

简单的来说就是可以帮助我们对一个url字符串进行格式化,并生成一个对象方便我们使用

使用方法(通过new操作符进行调用)

new URL(url: string | URL, base?: string | URL | undefined)

最终生成的对象将包含以下属性,我们可以通过new URL(...).[keyword]的形式获取我们所需要的属性值

// 每个属性对应的含义这里就不在详细介绍了,具体可查看
// https://developer.mozilla.org/en-US/docs/Web/API/URL
{
  href: 'http://www.example.com',
  origin: 'http://www.example.com',   
  protocol: 'http:',
  username: '',
  password: '',
  host: 'www.example.com',
  hostname: 'www.example.com',        
  port: '',
  pathname: '',
  search: '',
  searchParams: URLSearchParams {},   
  hash: ''
}

说了一大堆,感觉还是没说怎么用,别着急,请往下看

只存在url的情况我们不在这里进行讨论,下面我们主要讨论urlbase参数同时存时出现的几种使用情况

base参数存在pathname(不存在的情况与下面的结论一致)

// 这里使用mdn上的实例
const url = new URL('../cats', 'http://www.example.com/dogs');
// output
// {
//     href: 'http://www.example.com/cats',
//     origin: 'http://www.example.com',   
//     protocol: 'http:',
//     username: '',
//     password: '',
//     host: 'www.example.com',
//     hostname: 'www.example.com',        
//     port: '',
//     pathname: '/cats',
//     search: '',
//     searchParams: URLSearchParams {},   
//     hash: ''
//   }

我们可以清晰的看到href后面pathname被cats替换了,于是我们便可以的大胆的猜测,并得出一个结论①(经过多次常尝试后)

当base(非哈希内容)参数中存在pathname的话将会被url中的内容所覆盖

注意:在官方的实例中使用了../cats的url,我们其实也可以写成cats/cats./cats,结果将不会发生变化,我们以cats为例,打印如下

// 以cats为例的基础上再添加pathname=orange,search为size=2
const url = new URL('cats/search?size=2', 'http://www.example.com/dogs');
// output
// {
//     href: 'http://www.example.com/cats/search?size=2',
//     origin: 'http://www.example.com',
//     protocol: 'http:',
//     username: '',
//     password: '',
//     host: 'www.example.com',
//     hostname: 'www.example.com',
//     port: '',
//     pathname: '/cats/search',
//     search: '?size=2', // 打印出了search内容
//     searchParams: URLSearchParams { 'size' => '2' },
//     hash: ''
//   }

在结论①中我们提到base为非哈希内容的时候,name为哈希内容的时候又会怎么样呢?其实结果很简单就是在base参数的后面添加上在url上添加的hash内容,例子如下

// 我们可以清晰的看到打印的结果,并且并不会影响base的pathname
const url = new URL("#hash", "http://www.example.com/dogs");
// {
//     href: 'http://www.example.com/dogs#hash',
//     origin: 'http://www.example.com',        
//     protocol: 'http:',
//     username: '',
//     password: '',
//     host: 'www.example.com',
//     hostname: 'www.example.com',
//     port: '',
//     pathname: '/dogs',
//     search: '',
//     searchParams: URLSearchParams {},        
//     hash: '#hash'
//   }

以上就是参数填写时候的用法,我们在上面可以看到在打印出的内容中存在searchparams属性,该属性的值是URLSearchParams,那么该属性的究竟有什么用呢?,我们举例查看

  • 帮助我们通过search名称获取参数值(该方法在react中可以让我们自定义一个hook,通过传递固定值获取search参数值)
const url = new URL("http://www.example.com/dogs?name=张三&age=20");
const name = url.searchParams.get("name"); // output 张三
const age = url.searchParams.get("age"); // output 20

// 举例自定义react hook获取路径参数值 useSearchParams.ts
import { useLayoutEffect, useState } from 'react';

export default (keyword: string) => {
  const [searchParams, setSearchParams] = useState<string>();

  useLayoutEffect(() => {
    setSearchParams(new URL(location.href).search);
  }, []);

  return new URLSearchParams(searchParams).get(keyword);
};

// 在组件中使用
const name=useSearchParams('name')

在react-router的v6版本中我们可以

import { useSearchParams } from 'react-router-dom';

const [searchParams,setSearchParams]=useSearchParams()

const name=searchParams.get('name')

// seatSearchParams 可以动态的给url中添加searchparams,用法
 setSearchParams({age: '20'}) // 该设置将覆盖其他search参数
  • 帮助我们通过设置url参数
const url = new URL("http://www.example.com/dogs?name=张三&age=20");

 // 如果路径中存在改制,改值将会被替代未最新值
url.searchParams.set("sex", "1");

// 打印url.href如下
// http://www.example.com/dogs?name=%E5%BC%A0%E4%B8%89&age=20&sex=1

// 会一直添加,即使路径中存在也不会被覆盖
// url.searchParams.append("sex", "1"); 

URLSearchParams还有其他的功能,我认为这两点相对来说更重要一些,如果想要了解其他功能,可以去mdn查看,这里我就不详细说明了

最后我再简单说一下URL.createObjectURL()读取图片file对象生成img标签src可访问的链接,这里值注重实现

import { Upload } from 'antd';
import { RcFile } from 'antd/lib/upload';
import { useState } from 'react';

export default () => {
  const [url, setUrl] = useState<string>('');

  const beforeUpload = (file: RcFile) => {
    const url = URL.createObjectURL(file);
    setUrl(url);

    return false;
  };

  return (
    <>
      <Upload beforeUpload={beforeUpload}>上传</Upload>
      <img src={url} />
    </>
  );
};