解析没有路径但在查询中带有斜杠的 URL

Posted

技术标签:

【中文标题】解析没有路径但在查询中带有斜杠的 URL【英文标题】:Parsing an URL without a path but with a slash in the query 【发布时间】:2015-10-04 10:29:07 【问题描述】:

我在解析没有路径但查询中有斜杠的 URL 时遇到问题。例如:http://example.com?q=a/b

我知道这样的 URL 很可能是无效的 (*) - 它至少需要一个斜杠作为路径,如下所示:http://example.com/?q=a/b

我在其中尝试过此类 URL 的所有浏览器都会自动更正 URL。这基本上就是我想要重现的内容:识别并更正这样的 URL。

但使用 parse_url 会产生:

var_dump( parse_url('http://example.com?q=a/b') );

array(3) 
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(15) "example.com?q=a"
  ["path"]=>
  string(2) "/b"

虽然在查询中使用不带斜杠的 URL,但它可以正常工作:

var_dump( parse_url('http://example.com?q=ab') );

array(3) 
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(11) "example.com"
  ["query"]=>
  string(4) "q=ab"

我尝试过的所有外部库(Jwage\Purl、League\Url、Sabre\Uri)基本上都做同样的事情,这让我有点吃惊。

为什么(所有?)浏览器都“正确”,而(所有?)php 库却“错误”?

除了在解析 URL 之前尝试使用正则表达式捕获这些情况(这可能不可靠 - 这就是我想首先使用库的原因),我还有什么替代方法?

(*) 我咨询了三个来源:RFC 1738、RFC 3986、WHATWG URL Standard,他们三个都不同意什么被认为是有效的。

【问题讨论】:

有一个报告的错误讨论这个问题:bugs.php.net/bug.php?id=54369 【参考方案1】:

如果您仍想应用正则表达式,则应生成您要查找的 URL:

$url=pcre_replace('/([^/]+:\/\/[^/]+)\?/', '$1/?',$url);

它要求 URL 以至少一个字符的协议名称开头,后跟“://”,至少一个字符的域名(“localhost”也可以接受)。之后,它将在“?”之前插入“/”,但前提是“?”之前没有更多的“/”。

【讨论】:

正则表达式并不是真正的问题(除了我不想要误报)。我将使用:preg_match("~^(https?://(?:[a-z0-9-]+\.)*[a-z0-9-]+(?::\d+)?)(\?.*)~", ...) 好的,这可能会成功!我的解决方案是在使用 parse_url() 解析之前对字符串进行预处理 ...【参考方案2】:

WHATWG URL 标准最接近浏览器实现的内容。其他软件还没有完全对齐,尽管对于 PHP https://phppackages.org/p/esperecyan/url 可能有效。 (没试过。)

【讨论】:

以上是关于解析没有路径但在查询中带有斜杠的 URL的主要内容,如果未能解决你的问题,请参考以下文章

哪些工具会生成在路径标头中带有前导斜杠的存储库转储?

参数中带有斜杠的 URL?

http、https请求URL中带有&等特殊字符的解决方法

springboot中URL带有斜杠的转义字符百分之2F导致的400错误

url路径与用斜杠关闭的路径是不是有明显区别?

网络资源路径的双斜杠//和双反斜杠\的区别