你可以选择RFC3986行为(严格URI,"原始vs规范化解码")或浏览器风格的WHATWG行为(Unicode/IDNA、软错误、自动编码)。...更糟的是:团队往往混用:有些地方用解码后的值,有些地方用原始值,再加上散落在各处的临时解码逻辑。这种混乱很容易埋下隐蔽bug和安全隐患。...直到遇到:没有scheme/host的URL(相对URL),带userinfo/port的URL,已经编码过的值,需要rawurlencode()规则(RFC3986)的参数,应该原样保留的fragment.../bar/)默认端口(https的:443)如果你把URL当成纯字符串处理,要么:缓存/路由出现诡异问题,要么安全检查被绕过,因为你比较的是"错误的表示形式"。...RFC3986验证:严格URI解析+规范化选项如果你在验证通用URI(不只是HTTPURL),或者你关心rawvs规范化解码的表示,Uri\Rfc3986\Uri是个好选择。
编码注意事项 按照上面定义的语法排除的主机部分中的字符必须按照 RFC3987 中的规定从 Unicode 转换为 ASCII 或其替换字符。...除了由上面语法排除的字符外,其他组件的字符在第一次转换为 UTF-8 字符时,必须从 Unicode 码转化到 ASCII 码,然后使用百分比编码格式替换对应的定义在 URI RFC3896 字符和国际化资源标识符...编码注意事项 按照上面定义的语法排除的主机部分中的字符必须按照 RFC3987 中的规定从 Unicode 转换为 ASCII 或其替换字符。...除了由上面语法排除的字符外,其他组件的字符在第一次转换为 UTF-8 字符时,必须从 Unicode 码转化到 ASCII 码,然后使用百分比编码格式替换对应的定义在 URI RFC3896 字符和国际化资源标识符...这个之必须符合此规范第 4.1 节中的第 10 项要求—换句话说,这个之必须是 RFC2616 中定义的凭证。 子协议通用名 子协议名称,通常被称为子协议。
更麻烦的是,有两个主要标准在主导这一切:2005 年的 RFC 3986(https://datatracker.ietf.org/doc/html/rfc3986),这是 URI 的经典标准;以及 WHATWG...根据 RFC 3986,它是一个有效的相对路径 URL;但在 WHATWG 标准下,如果没有基 URL,它就是无效的。...这小错误就能让你的应用出大乱子。作为一个亲身经历过类似坑的开发者,我觉得是时候拥抱更安全的解决方案了。 欢迎新 API:安全、强大且易用 好消息来了!从 PHP 8.5 开始,一切都变了。...PHP 将在标准库中引入一个全新的“URI”扩展,它总是可用,并且提供了符合 RFC 3986 和 WHATWG URL 标准的解析器。这不仅仅是解析,还能轻松修改 URL 的各个组件。太棒了!...url->toRawString(), PHP_EOL; // Prints: HTTPS://thephp.foundation/sp%6Fnsor/ 运行这个代码,你会发现它优雅地处理了大小写、百分比编码和端口问题
如果一个属性的名称匹配到特定的正则表达式,则使用对于的模式来校验该属性的值。 如下表示使用S_开头的属性必须是字符串类型,而使用 I_ 开头的则必须是整数类型,并忽略不匹配正则表达式的属性。...RFC-3986中定义了基本URI和相对引用解析。 检索URI 用于获取模式的URI称为“检索URI”。...URI与检索URI相同 $id 可以在模式的根使用id关键字定义基本URI,id的值是一个URI引用,没有根据检索URI解析的片段。...最常见的方式是在指向该子模式的URI片段中使用JSON 指针 。 JSON指针描述了一个斜杠分隔的路径,用于遍历文档中对象中的键。...在子模式中使用id时,它表示一个嵌入的模式,它的标识符是id的值,该值根据它出现在其中的模式的基本URI进行解析。
这通常被称为绝对 URI,并且是 RFC 3986 中详细说明的唯一指定 URI 的形式。这个形式通常在向 HTTP 代理发出请求时使用。 认证形式 ,只包含认证信息。...UriInterface 是 RFC 3986 (主要用例)中指定的 HTTP 和 HTTPS URI 的模型。该接口提供了与各种 URI 部分交互的方法,这将消除重复解析 URI 的需要。.../html/rfc3986#section-3.3 110 * @return string URI 路径信息。...`字符不是查询字符串的一部分,**不该** 添加在返回值中。 120 * 121 * 返回的值 **必须** 是百分号编码,但 **不该** 对任何字符进行双重编码。...139 * 140 * 返回的值 **必须** 是百分号编码,但 **不该** 对任何字符进行双重编码。
如果你的value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和=符号进行转义,也就是对其进行编码。...RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。...,编码和不编码是等价的,但是对于上面提到的这些字符,如果不经过编码,那么它们有可能会造成Url语义的不同。...例如对于~符号,虽然RFC3986文档规定,对于波浪符号~,不需要进行Url编码,但是还是有很多老的网关或者传输代理会 如何对Url中的非法字符进行编码 Url编码通常也被称为百分号编码(Url Encoding...我们上面提到过,保留字符一般是用来分隔URI组件(一个URI可以被切割成多个组件,参考预备知识一节)或者子组件(如URI中查询参数的分隔符),如:号用于分隔scheme和主机,?号用于分隔主机和路径。
URI-reference = URI-reference, see [RFC3986], Section 4.1 absolute-URI = absolute-URI, see [RFC3986]...RFC3986], Section 3.1 authority = authority, see [RFC3986], Section 3.2 uri-host = host, see...RFC7230: 消息格式与路由 RFC7231: 语义与内容 RFC7232: 条件请求 RFC7233: 范围请求 RFC7234: 缓存 RFC7235: 认证 HTTP协议简介 协议是双方通信的约定...收发,并没有这么简单 收发的时候,还要做很多额外的约定,比如: 是否包含了COOKIE 是文档,还是图片? 使用什么语言编码? 数据总长度是多少? 是否允许缓存?缓存几时过期?...必须是这样的:我要2斤桔子,顺便帮我打包好,不要烂的。 HTTP协议的文档里,大概就约定了这些细节。不管是服务端,还是客户端,开发的时候必须遵循此文档。 我只是写写PHP,也需要了解这些?
其他一些更是莫名其妙的名字却没有问题……甚至后面那一段怎么看都觉得会引发错误的邮箱字段却一直没有 bug 出现 借此机会对 URL 进行一次深入而系统的学习 URL & URI what is URL1...就是说,URI 属于父类,而 URL 属于 URI 的子类。URL 是 URI 的一个子集。 二者的区别在于,URI 表示请求服务器的路径,定义这么一个资源。...实际上就是为了防止歧义, 无歧义的情况下直接输入完全没有问题, 然而更多时候我们需要对一些特定的字符进行转换 URI 编码标准 2005 年 1 月发布的 RFC 3986,强制所有新的 URI 必须对未保留字符不加以百分号编码...URI 文字类型 URI允许接受 2 类文字: Reserved Characters -- RFC 3986 Reserved Characters (January 2005) Encode...%3F @ 40% [ %5B ] %5D 这里解释了为何之前的 Email 没有出现和空格一样的错误, 因为@和.
query ] host = RFC3986], Section 3.2.2> port = RFC3986], Section...3.2.3> path = RFC3986], Section 3.3> query = RFC3986]...control frames mask: 1 masked,0 unmasked 当为1时,mask-key赋值,用于服务器端 unmask payload data 客户端发送到服务端的数据都必须...http的修改形式,修改了许多http非本质问题, Websocket API是完全事件驱动的,自动发送数据和通知。遵循异步编程模式。监听事件。open message error close。...ref:The WebSocket Protocol
WebSocket URIs(第三章协议正文) 这个规范使用在RFC5234中的ABNF语法以及URI规范中的RFC3986的术语和ABNF产品定义了两套方案。...= RFC3986](https://tools.ietf.org/html/rfc3986#section-3.4), 3.4节> 端口字段是可选的,默认的"ws..."端口是80,而默认的"wss"端口是443。...,表示非空的查询参数(query) 空查询参数(query) 在WebSocket URIs的里,身份标识片段是没有意义的,而且禁止使用在这些URI里面。...与任何的URI方案一样,"#"字符不是表示片段(fragment)开始时,都必须编码为%23。
如果你的value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和= 符号进行转义,也就是对其进行编码。 ...RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相 应的解释。 ... 需要注意的是,对于Url中的合法字符,编码和不编码是等价的,但是对于上面提到的这些字符,如果不经过编码,那么它们有可能会造成Url语义 的不同。...例如对于~符号,虽然RFC3986文档规定,对于波浪符号~,不需要进行Url编码,但是还是有很多老的网关或者传输代理会进行编码。 ...由于历史的原因,表单使用的Url编码实现并不符合最新的标准。
如果参数值中包含了 & 字符,那么会对 URL 解析造成影响,因此需要对造成歧义的 & 符号进行编码)URL 编码的规则URL 编码需要遵循 RFC 3986 标准。...RFC 3986: Uniform Resource Identifier (URI): Generic Syntax (rfc-editor.org)RFC3986 协议规定 URL 只允许包含两类字符...保留字符:“保留字符” 是那些具有特殊含义的字符,比如:斜线字符 / 用于 URL 不同部分的分界。常见的 “保留字符” 有:冒号 :(分隔协议 和 主机)、斜线 /(分隔主机 和 路径)、问号 ?...(比如,斜线字符 / 用于 URL 不同部分的分界,但是斜线字符 / 又需要出现在 URL 一个路径成分的内部)URL 编码一个 “保留字符”,首先需要把该 “保留字符” 的 ASCII 的值表示为两个...如果两个 URL 的差别仅在于 “未保留字符” 是用 URL 编码还是用字符自身表示,那么这两个 URL 具有等价的语义。
如果你的value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和=符号进行转义,也就是对其进行编码。...RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。...需要注意的是,对于Url中的合法字符,编码和不编码是等价的,但是对于上面提到的这些字符,如果不经过编码,那么它们有可能会造成Url语义的不同。...例如对于~符号,虽然RFC3986文档规定,对于波浪符号~,不需要进行Url编码,但是还是有很多老的网关或者传输代理会进行编码。...我们上面提到过,保留字符一般是用来分隔URI组件(一个URI可以被切割成多个组件,参考预备知识一节)或者子组件(如URI中查询参数的分隔符),如:号用于分隔scheme和主机,?号用于分隔主机和路径。
通过 URL 我们可以知道网络资源的位置以及访问它的协议。 URL 由互联网工程任务组织(IETF)URI 工作小组制定并成为一个互联网标准,收录于 RFC1738。...保留字符 许多 URL 方案将某些字符保留为一种特殊的含义:它们在 URL 的方案特定部分中的出现具有指定的语义。如果 URL 中出现了不表示其特殊含义的保留字符,则必须对保留字符进行编码。...6.2 URL 编码规则 RFC3986 规定了 URL 中非保留字符,即无需转义的没有任何特殊含义的字符,其定义如下: unreserved = ALPHA / DIGIT / "-" / "."...wd=%E6%98%A5%E8%8A%82 其中 0xE698A5 是汉字"春"的 UTF8 码值,0xE88A82 是汉字"节"的 UTF8 码值。...---- 参考文献 [1] rfc1738 [2] rfc3986 [3] URL 编码解码在线工具 [4] 查看字符编码(UTF-8) [5] 关于url编码标准的说明
问题复现 首先我们是通过get请求访问服务端,参数直接拼接在url中;与我们常规的get请求有点不一样的是其中一个参数要求url编码之后传过去。...因为不知道服务端的实现,所以再事后定位到这个问题之后,反推了一个服务端可能实现方式 1. web服务模拟 模拟一个接口,要求必须传入accessKey,且这个参数必须和我们定义的一样(模拟身份标志,用户请求必须带上自己的...方法提供关键URI生成逻辑,根据最后的返回可以知道,生成URI依然是使用URI.create,所以出问题的地方就应该是 uriComponents.encode() 实现url编码的地方了,对应的代码如下...encode Pchar 官方人员的解释如下 根据 RFC 3986 加号等符号的确实可以出现在参数中的,而且不需要编码,有问题的在于服务端的解析没有与时俱进 III....小结 最后复盘一下这个问题,当使用RestTemplate发起请求时,如果请求参数中有需要url编码时,不希望出现问题的使用姿势应传入URI对象而不是字符串,如下面两种方式 @Override @Nullable
URL编码是一个比较麻烦的事情,RFC 3986是关于URI的一个标准,在它的第2节定义了字符如何在URI中进行表示,而第3节把一个URI区分为scheme, hier-part, query, fragment...这个URL不需要进行百分号编码,因为每个component中都没有保留字,全部为字母、数字或者非保留的ASCII可见字符(见RFC 3986第2.3节)。...按理说应该解释为页面中的一个anchor,然而#comments只是url这个参数的一部分。另外,URL中含有汉字,也不符合标准。...所以编码是必须的,要针对各个component,以及query中的每个参数值做percent encoding....URL编码要求先将URL转换为一个UTF-8的字节序列,然后再做percent encoding, 这在RFC 3986和W3C的网站上都有介绍。
在深入了解规则之前,先看一下在 RFC 3986 中定义的通用 URI 语法,如下所示: URI = scheme "://" authority "/" path ["?"...query] ["#" fragment] 规则#1:URI中不应包含尾随的斜杠(/) 这是作为 URI 路径中最后一个字符的最重要的规则之一,正斜杠(/)不会增加语义值,并可能导致混淆。...规则#2:正斜杠分隔符(/)必须用于指示层次关系 在 URI 的路径部分的正斜杠(/),用于表示资源之间的层次关系。...RFC 3986 中将 URI 定义为区分大小写,但协议头和域名除外。...虽然你的语法常识会告诉你使用复数来描述资源的单个实例是错误的,但实际的答案是保持 URI 格式一致并且始终使用复数形式。
先跳过规则,URI的通用语法也适用与本文中的URI。RFC 3986定义了通用URI语法,如下所示: URI = scheme “://” authority “/” path [ “?”...query ][ “#” fragment ] 规则1:URI结尾不应包含(/) 这是作为URI路径中处理中最重要的规则之一,正斜杠(/)不会增加语义值,且可能导致混淆。...RFC 3986将URI定义为区分大小写,但scheme 和 host components除外。...URI格式规范(RFC 3986)认为该URI与URI#1相同。...keep-it-simple的原则在这里同样适用。虽然一些”语法学家”会告诉你使用复数来描述资源的单个实例是错误的,但实际上为了保持URI格式的一致性建议使用复数形式。