以下是一些URL:
http://sub.example.com/?feed=atom&hello=world
http://www.sub.example.com/?feed=atom&hello=world
http://sub.example.com/?hello=world&feed=atom
http://www.sub.example.com/?hello=world&feed=atom
http://www.sub.example.com/?hello=world&feed=atom
http://www.sub.example.com/?hello=world&feed=atom#123
如您所见,它们全都指向相同的页面,但URL格式不同。这是另外两个基本示例:
http://example.com/hello/
http://example.com/hello
两者都一样。
我想将URL 转换为一种标准格式,以便在将URL存储在数据库中时,可以轻松地检查URL字符串是否已存在于数据库中。数据库。
由于可以采用多种方式设置URL的格式,这令人感到困惑。
将URL转换为一种标准格式的确定性方法是什么?也许parse_url()
路线...?
如评论中所概述的,没有针对此问题的确定性解决方案,但目的是在不“检索” 情况下尽可能接近我们拥有的页。在发布赏金答案之前,请先阅读评论。
答案 0 :(得分:1)
parse_url
之后,
www
前缀
组合这些部分以获得规范的URL。
答案 1 :(得分:1)
我对报告配置保存功能有同样的问题。在我们的系统中,用户可以设计自己的销售报告(例如Jira的JQL);为此,我们使用get params作为条件,并使用片段标识符(在#之后)作为布局设置,如下所示:
http://example.com/report.php?since=20180101&until=20180806#sort=amount&color=blue
对于我们的系统,如果先将参数设置为“直到”而不是“开始”,则获取参数或#参数之后的顺序也无关紧要,因此对我们来说是相同的请求。
考虑到这一点,子域不在讨论之列,因为您必须使用重写技术(例如Apache中的301的mod_rewrite)来解决此问题,或者创建域异常池以在软件级别执行此操作。另外,不同的域可以指向不同的网站,因此您必须确定是否是一个好主意;在subdos中,“ www”很容易找出来,但是在其他情况下,它将浪费您时间。
服务器端可以帮助在查询部分获取变量。例如,在PHP中,您可以使用函数parse_str和$ _SERVER ['QUERY_STRING']获取数组,然后,您将需要使用asort()命令对其进行最终比较,以比较是否有相同的请求(array_diff函数)。>
不幸的是,服务器端不是一种选择,因为它无法获取哈希(#)内容,而且我们仍然没有考虑其他问题,例如包含的脚本名,协议或端口:
http://www.sub.example.com/index.php?hello=world&feed=atom
https://www.sub.example.com/?hello=world&feed=atom
http://www.sub.example.com:8081/?hello=world&feed=atom
以我个人的经验,最接近的解决方案是JavaScript,用于处理url,将查询部分解析为数组,对其进行比较并使用片段标识符进行相同的操作。如果需要在服务器端使用它,则必须在每个加载页面后跟随一个ajax请求,以将该数据发送到服务器。
对于我的回答长度,我们事先表示歉意,但这是我必须解决的同样问题。问候!
从URL获取协议,域和端口 Get protocol, domain, and port from URL
如何获取JavaScript中的查询字符串值? How can I get query string values in JavaScript?
如何从URL获取片段标识符(哈希号后的值)? How do I get the fragment identifier (value after hash #) from a URL?
答案 2 :(得分:1)
将首选的<link rel="canonical" ... >
标签添加到HTML标头中是唯一可靠的解决方案,以便将唯一的内容引用到单个SEF URL
中。请参阅Google关于Consolidate duplicate URLs的文档,该文档可能比我以往所能回答的问题更加自动和可靠。
在不解析服务器的.htaccess
重写规则或HTML标头的情况下,能够知道规范URL或解析一堆外部URL的想法似乎并不适用(原因是因为维护一个带有URL别名的表,该别名随后不允许猜测如何重写HTTP请求。
这个问题可能属于https://webmasters.stackexchange.com/search?q=cannonical。
答案 3 :(得分:1)
由于问题被标记为“ PHP”,因此我假设您在后端。
您有足够的答案可以比较 URL (协议,主机,端口,路径,请求参数列表),其中路径区分大小写,协议和主机不区分大小写。严格来说,更改请求参数的顺序也会更改URL。
我的印象是,您希望通过服务器所服务的 RESOURCE 来区分(http://www.sub.example.com/与http://sub.example.com/服务相同的资源,或者... / hello服务于服务器与... / hello /)相同的资源
提供哪些资源,您应该完全了解后端级别,因为您(后端)知道您正在提供什么。找到该资源的完美ID并使用它。
PS:URL并不是一个好的标识符。但是,如果您必须使用它,只需使用经过清理的版本(出于您的目的进行清理=>清理到您首选的主机,在路径末尾去除或添加斜杠,从路径中删除/../之类的东西(无论如何安全性问题),不管您的目的是什么,请求参数都以特定顺序排列。
最好的问候,iPirat
答案 4 :(得分:1)
使用重复的URL就是这种情况,您可以通过使用URL工厂将所有不合适的URL重定向到正确的URL来避免这种重复的URL。
这篇文章也解释了同样的事情:
https://www.tinywebhut.com/remove-duplicate-urls-from-your-website-38
指向同一页面的所有其他URL都被重定向到301的正确版本。
这是搜索引擎优化(SEO)的最佳做法。在这里,我将给您提供一些示例。
您可以考虑此网站的URL,例如此页面的错误链接
https://stackoverflow.com/questions/51685850
https://stackoverflow.com/questions/51685850/convert-url-into-one-s
https://stackoverflow.com/questions/51685850/
如果您转到此页面的上述错误网址,您将被重定向到正确的网址,即
https://stackoverflow.com/questions/51685850/convert-url-into-one-standard-format
如果您更改了此问题的标题,则所有其他URL都将被重定向到301,以正确的URL。这里的想法是301重定向,它告诉搜索引擎用新的URL替换旧的URL,否则搜索引擎会找到提供相同内容的不同URL。
这里真正的问题是问题的编号51685850
。该ID用于根据数据库中的信息创建正确的URL。使用提供的链接中的文章中创建的URL工厂,您甚至不需要将URL存储在数据库中。
您可以在此处阅读有关重复内容的更多信息:
https://moz.com/learn/seo/duplicate-content
同样的规则也适用于tinywebhut.com,错误的URL是
https://www.tinywebhut.com/remove-duplicate-38
https://www.tinywebhut.com/some-text-38
https://www.tinywebhut.com/remove-duplicate-urls-from-your-website-38/
在上述URL中,ID附加到URL的末尾38
,并且如果您转到这些URL中的任何一个,您将被重定向到301的正确版本,即< / p>
https://www.tinywebhut.com/remove-duplicate-urls-from-your-website-38
由于本文已经完成了此操作,因此我没有做任何功能来解释这一点:
https://www.tinywebhut.com/remove-duplicate-urls-from-your-website-38
您可以通过几个非常简单的功能实现目标,并且可以应用相同的想法删除其他重复的URL,例如/about.php
,/about
,/about.php/
,{{1 }} 等等。为此,您只需要为现有功能添加一些代码即可。
一种替代方法是添加规范标记,例如,即使您有多个URL可以访问同一页面,您也只需应用规范标记并将链接添加到正确的URL。
/about/
通过这种方式,您告诉搜索引擎应该将多个URL视为一个,并且搜索引擎会在其搜索结果中添加规范标记中使用的链接。您可以在此处阅读有关规范化的更多信息:
https://moz.com/learn/seo/canonicalization
但摆脱重复内容的最佳方法仍然是301重定向。如果您像我一开始所说的那样进行了301重定向,那么所有问题都会得到解决,而不会感到意外。
答案 5 :(得分:1)
我的原始答案假设页面都归OP所有,如“您所看到的,它们都指向完全相同的页面,但URL格式不同...”这一行。我正在调整答案以处理多个选项,并添加了您可以对URL做出的假设以及对URL不能做出的假设的列表。
正如其他人指出的那样,如果您不知道页面相同,则没有明确的简单答案。但是,如果遵循这些假设,则应该安全地标准化一些内容:
CAN ASSUME
具有相同值的查询字符串指向相同位置,而不管顺序如何。示例:https://example.com/?fruit=apple&color=red与https://example.com/?color=red&fruit=apple
301重定向到特定来源。如果您收到301重定向响应,请遵循重定向并使用该URL。您可以放心地假设,如果URL实际上确实指向同一页面,并且页面排名得到了优化,那么您可以关注它。
如果HTML中只有一个<link rel="canonical">
标签,那么该标签也可以用于覆盖规范链接(原因请参见下文)。
无法假设
任何URL都可以保证与其他URL相同(如果它们不同)(在这种情况下,我所说的URL是查询字符串之前的任何内容)。
任何两个URL,即使它们当前具有完全相同的内容,也将保持完全相同的内容。一个示例为https://example.com/test和https://sub.example.com/test。两者都可能设置为相同的通用测试页面内容。将来,https://sub.example.com/test可能会更改。您不能以为不会。
以所需的URL格式的第一部分重定向所有流量:是否要www.example.com
或example.com
或sub.example.com
?是否要使用斜杠?首先使用服务器规则或PHP进行重定向。这对于搜索页面排名(如果对您而言很重要)也非常有用。
例如:
if (!$_SERVER['HTTPS'] || 'example.com' !== $_SERVER['HTTP_HOST'] || rtrim($_SERVER['PHP_SELF'], '/') !== $_SERVER['PHP_SELF']) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: '. 'https://example.com/'.rtrim($_SERVER['PHP_SELF']), '/'));
exit;
}
最后,要管理所有其他SEO问题,您可以添加以下HTML标签:
`<link rel="canonical" href="<?php echo $url; ?>">`
即使您不控制站点,也可以假定查询顺序无关紧要。为了对此进行标准化,请查询并重建参数,然后将其附加到规范化的URL。
function getSortedQuery()
{
$url = [];
parse_str($_SERVER['QUERY_STRING'], $url);
ksort($url);
return http_build_query($url);
}
$url = $_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.getSortedQuery();
另一种选择是获取页面内容,查看是否有<link rel="canonical">
字符串,然后使用该字符串记录数据。这会花费更多,因为它需要整个页面加载。
要重复一遍,请确保获取301重定向,因为它们不是建议,而是关于最终结果URL的指令。
我可能建议使用两列,一列是“ canonical_url”,另一列是“ effective_url”。有时,URL有效,然后在以后变为301重定向。这只是我的看法,但我想知道这些事情。
答案 6 :(得分:1)
所有答案都有重要信息。假设您使用的是类似Apache的服务器,对于URL位,我将使用.htaccess(或者,最好是,如果您可以更改-等效的服务器Apache配置文件)来进行重写。举个简单的例子:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule (.*) http://example.com/$1 [R=Permanent]
在此示例中,“ R=Permanent
”确实进行了重定向。这通常不是什么大问题,因为a)它告诉浏览器记住重定向,并且b)您的内部链接可能是相对的,因此协议(http或https)和服务器(example.com或其他)都得以保留。因此,通常,重定向将是每个会话一次或更短的时间-IMO为了避免在PHP中完成所有这些操作花了很长时间。
我想您也可以用它来重写查询位的顺序,尽管当查询位很重要时,我倾向于(不建议您这样做,只是说')将它们添加到我的路径中(例如,重写“ .../blah/atom
”到“ .../blah.php?feed=atom
”)。无论如何,都有大量的重写技巧,我建议您在中阅读它们。
Apache mod_rewrite。
如果您确实选择了这种方法,请务必仔细考虑您要发生的事情-一旦开始使用URL进行处理,通常就会长时间停留在您的决策中。
答案 7 :(得分:0)
正如一些人指出的那样,尽管您显示的URL当前可能指向相同的内容,但无法确定将来是否会出现。协议或主机名的更改都可以为您提供不同的内容集,即使example.com
与www.example.com
,即使由同一IP的同一台计算机提供服务也是如此。虽然不常见,但可能会发生...
因此,如果我要维护URL列表,则将存储协议,主机名,目录路径,文件名(如果存在)(也就是“在问号前的最后一个斜杠之后出现的所有内容”),并按GET参数的键/值对
然后不要忘记,您可以转到https://www.google.com
,但不带任何协议和主机名...
答案 8 :(得分:-1)
避免在url中传递参数。使用JSON将参数传递到网页。