使用React Router Dom如何移除URL中的%20?
解决React Router中动态路由参数空格显示为%20的问题
我来帮你搞定这个问题!首先得先理清楚背后的原因:URL规范里空格属于特殊字符,浏览器会自动把它编码成%20,这是HTTP协议的硬性要求。不过你想要地址栏保留原始空格而非编码后的字符,也是有可行方案的,下面分步骤给你说明:
一、跳转时直接使用带空格的完整路径
当你通过history.push或者Link组件跳转时,别用参数化的路由写法,直接拼接带空格的完整URL字符串就行。
比如,别这么写(这种写法会自动编码参数,导致地址栏出现%20):
history.push({ pathname: "/guide/:name/:id", params: { name: "test of url", id: 1 } }); // 或者Link组件的参数写法 <Link to={{ pathname: "/guide/:name/:id", params: { name: "test of url", id: 1 } }}> 跳转 </Link>
改成直接用带空格的完整路径:
// 使用history.push直接跳转带空格的URL history.push("/guide/test of url/1"); // Link组件直接写完整路径 <Link to="/guide/test of url/1">跳转</Link>
这样浏览器地址栏会保留空格显示,同时React Router的动态路由/guide/:name/:id也能正确匹配,你通过useParams()获取到的name参数会自动解码为test of url。
二、处理用户直接输入/刷新后的编码URL
如果用户手动在地址栏输入带空格的URL,浏览器会自动把它编码成%20,这时候可以在目标组件里做跳转修正,把编码后的URL替换成带空格的版本:
import { useParams, useLocation, useHistory } from "react-router-dom"; import { useEffect } from "react"; function Pro() { const { name, id } = useParams(); const location = useLocation(); const history = useHistory(); useEffect(() => { // 提取URL中的name部分 const pathSegments = location.pathname.split("/"); if (pathSegments.length >= 3) { const encodedName = pathSegments[2]; const decodedName = decodeURIComponent(encodedName); // 如果当前URL的name是编码后的,就替换为解码后的版本 if (encodedName !== decodedName) { const newPath = `/guide/${decodedName}/${id}`; // 使用replace避免添加多余的历史记录 history.replace(newPath); } } }, [name, id, location, history]); return ( <div> <p>当前名称:{name}</p> <p>当前ID:{id}</p> </div> ); }
这段代码会在组件挂载或路由参数变化时,检查当前URL的name部分是否被编码,如果是就自动跳转到带空格的URL,地址栏会显示原始空格。
注意事项
虽然这种方法能满足视觉需求,但从HTTP规范角度来说,URL中的空格应该被编码,部分老旧浏览器或服务器可能无法正确处理带空格的URL,导致请求异常。如果不是必须的场景,建议接受%20的编码形式,这是更标准的做法。
内容的提问来源于stack exchange,提问作者tetar
相关产品推荐
相关产品推荐

