人们谈论URL,URI和URN就好像它们是不同的东西,但它们看起来与肉眼相同.
它们之间有什么区别?
哪些字符使网址无效?
这些有效的网址是?
example.com/file[/].htmlhttp://example.com/file[/].html我有一个关于网址的问题:
我已经阅读了RFC 3986,但仍然有一个关于一个URL的问题:
如果URI包含权限组件,则路径组件
必须为空或以斜杠("/")字符开头.如果URI不包含权限组件,则路径不能
以两个斜杠字符("//")开头.此外,URI引用
(第4.1节)可以是相对路径引用,在这种情况下,
第一个路径段不能包含冒号(":")字符.ABNF
需要五个单独的规则来消除这些情况的歧义,其中只有一个与给定URI引用中的路径子字符串匹配.我们使用通用术语"路径组件"来描述
解析器与其中一个规则匹配的URI子字符串.
我知道,这//server.com:80/path/info是有效的(它是一个架构相对URL)
我也知道这http://server.com:80/path//info是有效的.
但我不确定以下一个是否有效:
http://server.com:80//path/info
Run Code Online (Sandbox Code Playgroud)
我的问题背后的问题是,http://server.com:80//path/info当URI http://server.com:80/path/info由限制创建时,不会发送cookie/path
在RFC 3986 URI:通用语法规格列出分号作为保留(子DELIM)字符:
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
Run Code Online (Sandbox Code Playgroud)
";"的保留目的是什么?URI中的分号?就此而言,其他子delim的目的是什么(我只知道"&","+"和"="的用途)?
我试图在相关的RFC,IETF RFC 3986中找到它,但无法弄清楚.
HTTP的URI是否允许Unicode或任何类型的非ASCII?
您能否引用支持您答案的部分和RFC.
注意:对于那些可能认为这与编程不相关的人来说 - 确实如此.它与我正在构建的ISAPI过滤器有关.
附录
我已经阅读了RFC 3986的第2.5节.但是RFC 2616,我认为是当前的HTTP协议,早于3986,因此我认为它不能与3986兼容.此外,即使或当HTTP RFC更新后,仍然存在合理化问题 - 换句话说,HTTP URI是否支持所有RFC3986条款,包括哪些适合包含非US-ASCII字符?
我们正在从Java 8迁移到Java 11,因此,从Spring Boot 1.5.6迁移到2.1.2.我们注意到,当使用RestTemplate时,'+'符号不再编码为'%2B'(由SPR-14828更改).这没关系,因为RFC3986没有将'+'列为保留字符,但在Spring Boot端点接收时它仍被解释为''(空格).
我们有一个搜索查询,可以将可选的时间戳作为查询参数.查询看起来像http://example.com/search?beforeTimestamp=2019-01-21T14:56:50%2B00:00.
我们无法弄清楚如何发送编码加号,而不进行双重编码.查询参数2019-01-21T14:56:50+00:00将被解释为2019-01-21T14:56:50 00:00.如果我们要对参数self(2019-01-21T14:56:50%2B00:00)进行编码,那么它将被接收并解释为2019-01-21T14:56:50%252B00:00.
另一个约束是,我们希望在设置restTemplate时将基本URL设置在别处,而不是在执行查询的位置.
或者,有没有办法强制"+"不被端点解释为''?
我写了一个简短的例子,演示了一些实现更严格编码的方法,其缺点是作为评论解释:
package com.example.clientandserver;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
@RestController
public class ClientAndServerApp implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ClientAndServerApp.class, args);
}
@Override
public void run(String... args) {
String beforeTimestamp = "2019-01-21T14:56:50+00:00";
// …Run Code Online (Sandbox Code Playgroud) 是否有一个类String根据RFC 3986规范对通用进行编码?
那就是:"hello world"=> "hello%20world" 不(RFC 1738):"hello+world"
谢谢
假设一个绝对的http或https URL.我正在寻找路径前面的URL部分的"官方"或普遍接受的名称.
http://foo:bar@example.com:8042/over/there?name=ferret#nose
\_____________________________/
|
this part
Run Code Online (Sandbox Code Playgroud)
RFC 3986定义了URL语法部分,如下所示:
http://foo:bar@example.com:8042/over/there?name=ferret#nose
\__/ \______________________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
Run Code Online (Sandbox Code Playgroud)
RFC 6454定义URL的原点(如"同源")作为三元组(方案,主机,端口):
http://foo:bar@example.com:8042/over/there?name=ferret#nose
\__/ \______________/
\________________/
|
origin
Run Code Online (Sandbox Code Playgroud)
因此,这两个术语都不合适.我正在看的那个部分有一个好的术语,还是我坚持"计划(加://)加权限"?
我相信Java的URI.resolve方法的定义和实现与RFC 3986第5.2.2节不兼容.我知道Java API定义了该方法的工作方式,如果它现在被更改,它会破坏现有的应用程序,但我的问题是:任何人都可以确认我的理解这个方法与RFC 3986不兼容吗?
我正在使用这个问题中的示例:java.net.URI仅针对查询字符串进行解析,我将在此处复制:
我正在尝试使用JDK java.net.URI构建URI.我想附加一个绝对URI对象,一个查询(在String中).例如:
URI base = new URI("http://example.com/something/more/long");
String queryString = "query=http://local:282/rand&action=aaaa";
URI query = new URI(null, null, null, queryString, null);
URI result = base.resolve(query);
Run Code Online (Sandbox Code Playgroud)
理论(或我认为)是决心应该回归:
http://example.com/something/more/long?query=http://local:282/rand&action=aaaa
Run Code Online (Sandbox Code Playgroud)
但我得到的是:
http://example.com/something/more/?query=http://local:282/rand&action=aaaa
Run Code Online (Sandbox Code Playgroud)
我对RFC 3986第5.2.2节的理解是,如果相对URI的路径为空,那么将使用基URI的整个路径:
if (R.path == "") then
T.path = Base.path;
if defined(R.query) then
T.query = R.query;
else
T.query = Base.query;
endif;
Run Code Online (Sandbox Code Playgroud)
并且仅当指定了路径时才是要与基本路径合并的相对路径:
else
if (R.path starts-with "/") then
T.path = remove_dot_segments(R.path);
else
T.path = merge(Base.path, R.path);
T.path = remove_dot_segments(T.path);
endif; …Run Code Online (Sandbox Code Playgroud) 根据RFC 3986,以下字符是保留的,需要进行百分比编码才能在URI中使用,而不是作为其保留用途:
:/?#[]@!$&'()*+,;=
此外,它指定了一些特别保留的字符:a-zA-Z0-9\-._~
似乎很清楚,一般应该编码保留字符(以防止误解)而不编码未保留字符(为了便于阅读),但是如何处理不属于任何类别的字符?例如{,}并没有出现在任何一个列表中,但它们是标准的ASCII字符.
期待现代浏览器的指导,似乎它们有时会有不同的行为.例如,考虑将URL粘贴https://www.google.com/search?q={到Web浏览器的地址栏中:
https://www.google.com/search?q=%7B但是,如果一个粘贴https://www.google.com/#q={(删除"搜索"并将其更改?为a #,使角色成为片段/哈希而不是查询字符串),我们会发现:
https://www.google.com/#q=%7B(通过JavaScript)https://www.google.com/#q=%7B(在执行JavaScript之前)此外,当使用JavaScript异步执行请求时(即使用此MDN示例修改为使用URL ?q={),URL不会自动进行百分比编码.(我猜这是因为XMLHttpRequest API假定事先对URL进行编码/转义.)
我想(出于与奇怪的客户要求有关的原因)使用{和}在URL的文件名部分中没有(1)破坏事物,理想情况下也没有(2)在现代网络面板中创建丑陋的百分比编码条目浏览器的网络检查员/调试员.
rfc3986 ×10
uri ×5
url ×5
http ×4
java ×3
character ×1
cookies ×1
encode ×1
isapi ×1
query-string ×1
relative-url ×1
spring ×1
spring-boot ×1
timestamp ×1
unicode ×1
urn ×1
validation ×1