绝对URL与相对URL

280
我想了解这两种类型的URL之间的区别:相对URL(用于图片、CSS文件、JavaScript文件等)和绝对URL。
此外,哪一种更好使用?

https://www.seoclarity.net/resources/knowledgebase/difference-relative-absolute-url-15325/ - Channa
12个回答

325

我应该使用绝对URL还是相对URL?

如果你说的绝对URL是指包含协议(例如HTTP / HTTPS)和主机名(例如yourdomain.example)的URL,那么永远不要这样做(对于本地资源),因为这样会很难维护和调试。

假设你在代码中到处都使用了绝对URL,比如<img src="http://yourdomain.example/images/example.png">。现在当你要进行以下操作时会发生什么:

  • 切换到另一个协议(例如HTTP -> HTTPS)
  • 切换域名(test.yourdomain.example -> yourdomain.example

在第一个例子中,你将收到关于页面上请求不安全内容的警告。因为所有的URL都是硬编码为使用http(://yourdomain.example/images/example.png)。而当在HTTPS上运行页面时,浏览器期望所有资源都通过HTTPS加载,以防止信息泄漏。

在第二个例子中,当从测试环境上线你的网站时,这意味着所有资源仍然指向你的测试域而不是你的正式域。

所以回答你关于使用绝对URL还是相对URL的问题:总是使用相对URL(用于本地资源)。

不同类型的URL有什么区别?

首先让我们来看一下可以使用的不同类型的URL:

  • http://yourdomain.example/images/example.png
  • //yourdomain.example/images/example.png
  • /images/example.png
  • images/example.png
这些URL尝试访问服务器上的哪些资源?在下面的示例中,我假设网站从服务器上的以下位置运行:/var/www/mywebsite

http://yourdomain.example/images/example.png

上述(绝对)URL尝试访问资源/var/www/website/images/example.png。对于从自己的网站请求资源,您应该始终避免使用这种类型的URL,理由如上所述。然而,它确实有适用的场景。例如,如果您有一个网站http://yourdomain.example,并且想要通过HTTPS请求外部域的资源,您应该使用这种URL。例如,https://externalsite.example/path/to/image.png。

//yourdomain.example/images/example.png

这个URL是基于当前使用的方案相对的,几乎总是在包含外部资源(图片、JavaScript文件等)时使用。

这种类型的URL使用所在页面的当前方案。这意味着你在页面 http://yourdomain.example 上,并且在该页面上有一个图像标签 <img src="//yourdomain.example/images/example.png">,图像的URL将解析为 http://yourdomain.example/images/example.png。 当你在页面 https://yourdomain.example 上,并且在该页面上有一个图像标签 <img src="//yourdomain.example/images/example.png">,图像的URL将解析为 https://yourdomain.example/images/example.png

这样可以避免在不需要时通过HTTPS加载资源,并在需要时自动确保资源通过HTTPS请求。

上述URL在服务器端与前一个URL以相同的方式解析:

上述(绝对)URL尝试访问资源 /var/www/website/images/example.png

/images/example.png

对于本地资源,这是首选的引用方式。这是一个基于您网站的文档根目录(/var/www/mywebsite)的相对URL。这意味着当您有<img src="/images/example.png">时,它将始终解析为/var/www/mywebsite/images/example.png
如果您决定在某个时候切换域名,它仍然可以正常工作,因为它是相对路径。

images/example.png

这也是一个相对URL,尽管与之前的有些不同。这个URL是相对于当前路径的。这意味着它将根据您在网站中的位置解析为不同的路径。
例如,当您在页面http://yourdomain.example上使用时,它会按预期在服务器上解析为/var/www/mywebsite/images/example.png,但是当您在页面http://yourdomain.example/some/path上使用完全相同的图像标签时,它突然会解析为/var/www/mywebsite/some/path/images/example.png。
何时使用什么?
当请求外部资源时,您很可能希望使用与方案相关的URL(除非您想强制使用不同的方案),而处理本地资源时,您希望使用基于文档根目录的相对URL。
示例文档:
<!DOCTYPE html>
<html>
    <head>
        <title>Example</title>
        <link href='//fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700' rel='stylesheet' type='text/css'>
        <link href="/style/style.css" rel="stylesheet" type="text/css" media="screen"></style>
    </head>
    <body>
        <img src="/images/some/localimage.png" alt="">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
    </body>
</html>

一些(某种)重复项


2
使用绝对URL是否比使用相对URL加载页面更快?(解析相对路径需要花费多少时间?) - shasi kanth
2
任何可能的差异都非常微小,如果可以测量的话,那就不是你应该担心的事情。 - PeeHaa
3
不带协议的引入 Google Jquery 的示例: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script> - shasi kanth
10
假设绝对URL并非动态生成,这个答案解决了所提到的每一个问题。 - None
2
J.Money是正确的。现代Web框架具有“反向路由”的概念,允许您从一个页面创建到另一个页面的URL(必须是同一网站中的另一页)。这些允许您为URL命名,然后使用此名称而不是URL。这样,如果您想要更改URL,则可以在一个地方更改URL,因为其他所有地方都只引用该URL的名称。 - Kevin Wheeler
显示剩余7条评论

211

一般来说,最好使用相对URL以便您的网站不会受到其当前部署位置的基本URL的限制。例如,它将能够在localhost上正常工作,并且无需修改即可在您的公共域上使用。


6
+1 我同意。可能有时候使用绝对 URL 更好,比如当使用 CDN 时,或者当你需要更改网站的内容。在我看来,搜索域名要比搜索相对 URL 容易得多。 - Sune Rievers
71
为了维护方便,使用根相对路径的URL比包含域名更容易。例如,在StackOverflow上,使用纯根相对路径URL '/questions/2005079/absolute-vs-relative-urls' 来链接到此问题。路径前面的 '/' 表示该URL是根相对路径。当您需要移动文件或更改项目目录结构时,这种方法会更加实用。 - Mike
10
但是,你能做到吗?我绝对是使用这种方法的粉丝/支持者,但是在一个更大的框架中进行大规模重构通常是一项令人望而却步/恐惧的任务。尽管你认为你可能已经将它们全部切换了,在一个智能的IDE中,通常情况下它们会被忽略,如果它们被编码成字符串或动态创建的话。最糟糕的部分是通常那些被忽略的引用直到你的解决方案重新进入生产环境后才被发现... :( - dudewad
2
我曾经使用以/开头的绝对URL,这样可以轻松地将应用程序移动到另一台服务器上,但是当我将我的应用程序部署在www.mydomain.com/apps/时,我无法找到任何资源。因此,我同意相对URL更安全-尽管当您在不同路由中重用服务器端模板时,它们可能会出现问题,但在渲染之前,您可以轻松使用header-redirects将用户发送到正确的路径。 - Tarion
2
一个URL可以是相对的吗?难道不是协议的存在才构成了URI和URL吗? - dev_willis
显示剩余8条评论

82
查看示例URI(维基百科)。
foo://username:password@example.com:8042/over/there/index.dtb;type=animal?name=ferret#nose
\ /   \________________/\_________/ \__/            \___/ \_/ \_________/ \_________/ \__/
 |           |               |       |                |    |       |           |       |
 |       userinfo         hostname  port              |    |       parameter query  fragment
 |    \_______________________________/ \_____________|____|____________/
scheme                |                               | |  |
 |                authority                           |path|
 |                                                    |    |
 |            path                       interpretable as filename
 |   ___________|____________                              |
/ \ /                        \                             |
urn:example:animal:ferret:nose               interpretable as extension

绝对URL包括“路径”部分之前的部分 - 换句话说,它包括方案(在http://foo/bar/baz中的http)和主机名(在http://foo/bar/baz中的foo)(以及可选的端口、用户信息和端口)。
相对URL以路径开头。
绝对URL是完全的:只需查看URL本身就可以解析资源的位置。相对URL在某种意义上是不完整的:要解析它,您需要方案和主机名,这些通常从当前上下文中获取。例如,在一个网页中。
http://myhost/mypath/myresource1.html

你可以这样放置一个链接
<a href="pages/page1">click me</a>

在链接的href属性中,使用了相对URL,并且如果被点击,必须解析以便跟随它。在这种情况下,当前上下文是什么。
http://myhost/mypath/myresource1.html

所以这些的模式、主机名和前导路径被取出并添加到pages/page1之前,得到的结果是
http://myhost/mypath/pages/page1

如果链接是这样的:
<a href="/pages/page1">click me</a>

(注意URL开头出现的/)那么它将被解析为
http://myhost/pages/page1

因为前导的/表示主机的根。
在Web应用程序中,我建议对于属于您的应用程序的所有资源都使用相对URL。这样,如果您更改页面的位置,一切都将继续工作。任何外部资源(可以是完全位于应用程序之外的页面,但也可以是通过内容分发网络提供的静态内容)应始终使用绝对URL指向:如果不这样做,就没有办法找到它们,因为它们位于不同的服务器上。

10
相对URL不需要以URL路径开头。//example.com/…?foobar#foobar也是相对URL,不以URL路径开头(好吧,对于?foobar,您可以说它以一个路径开头)。 - Gumbo
@Gumbo,//example.com/… 这种类型的URL被称为相对路径吗?这对我来说很新奇。 - törzsmókus
4
根据RFC 2396中的说法:“相对URI引用与绝对URI有所区别,因为它们不以方案名称开头。” - Gumbo

66

假设我们正在创建一个子站点,其文件位于文件夹http://site.ru/shop中。

1. 绝对URL

Link to home page
href="http://sites.ru/shop/"

Link to the product page
href="http://sites.ru/shop/t-shirts/t-shirt-life-is-good/"

2. 相对 URL

Link from home page to product page
href="t-shirts/t-shirt-life-is-good/"

Link from product page to home page
href="../../"

虽然相对URL看起来比绝对URL短,但是绝对URL更可取,因为链接可以在网站的任何页面上不变地使用。

中间情况

我们考虑了两种极端情况:“完全”绝对和“完全”相对URL。但是在这个世界上,一切都是相对的。这也适用于URL。每次你谈到绝对URL时,你应该总是指相对于什么。

3. 协议相对URL

Link to home page
href="//sites.ru/shop/"

Link to product page
href="//sites.ru/shop/t-shirts/t-shirt-life-is-good/"

谷歌建议使用此类URL。然而,现在普遍认为http://和https://是不同的网站。

4.根相对URL

即相对于域的根文件夹。

Link to home page
href="/shop/"

Link to product page
href="/shop/t-shirts/t-shirt-life-is-good/"

如果所有页面都在同一个域内,使用基于相对路径的URL是个不错的选择。当你将网站移到另一个域时,不必对所有的URL进行大规模的域名替换。

5. 基于根目录的URL(也称为主页相对路径)

<base>标签指定了基础URL,它会自动添加到所有相对链接和锚点上。但是<base>标签不会影响绝对链接。我们会将主页作为基础URL进行指定:<base href="http://sites.ru/shop/">。

Link to home page
href=""

Link to product page
href="t-shirts/t-shirt-life-is-good/"

现在你不仅可以将你的网站移动到任何域名,还可以移动到任何子文件夹中。但请记住,尽管URL看起来像是相对路径,实际上它们是绝对路径。

特别注意锚点。要在当前页面内导航,我们必须写href="t-shirts/t-shirt-life-is-good/#comments"而不是href="#comments"。后者将会跳转到主页。

结论

对于内部链接,我使用基于基础路径的相对URL(5)。对于外部链接和新闻通讯,我使用绝对URL(1)。


1
太棒了的回答。可惜它在页面上停留得太低,人们看不到它。它回答了其他回答中很多评论。 - oligofren

25

实际上,有三种类型应该明确讨论。但在实践中,URL已经被抽象为在较低级别处理,我甚至可以说开发人员可能在他们的整个生涯中都不需要手动编写一个URL。

绝对链接

绝对链接将您的代码与协议和域名捆绑在一起。动态URL可以解决此问题。

<a href=“https://dev.example.com/a.html?q=”>https://dev.example.com/a.html?q=</a>

绝对链接优点:

  1. 可控性 - 子域名和协议都可以被控制。访问一个不常用的子域名的人会被引导到正确的子域名。你可以根据需要在安全和非安全之间切换。

  2. 可配置性 - 开发人员喜欢一切都是确定的。使用绝对链接可以设计出漂亮的算法。URL可以被配置,这样只需要在单个配置文件中进行一次更改就可以在整个站点范围内更新URL。

  3. 洞察力 - 你可以搜索正在抓取你网站内容的人或者获取一些额外的外部链接。


根相对路径

根相对路径将你的代码与基础URL绑定在一起。这可以通过动态URL和/或base标签来克服。

<a href=“/index.php?q=”>.example.com/index.php?q=</a>

根路径优点:

  1. 可配置性 - 使用基础标签可以将它们相对于您选择的任何根目录,使得切换域名和实现模板变得容易。

相对路径

相对路径将您的代码与目录结构绑定在一起。无法克服这一点。相对路径仅在文件系统中用于遍历目录或作为琐碎任务的快捷方式。

<a href=“index.php?q=”>index.php?q=</a>
<link src=“../.././../css/default.css” />

相对路径的缺点:

  1. 容易混淆 - 这是几个点?这是多少个文件夹?文件在哪里?为什么它不起作用了?

  2. 维护困难 - 如果一个文件被意外移动,资源将停止加载,链接会发送用户到错误的页面,表单数据可能会被发送到错误的页面。如果必须要移动一个文件,则需要更新所有将停止加载的资源和所有将变得不正确的链接。

  3. 无法扩展 - 当网页变得更加复杂,并且视图开始在多个页面之间重复使用时,相对链接将与它们所包含的文件相关。如果您有一个在每个页面上都会出现的导航HTML片段,那么相对路径将与许多不同的位置相关联。当人们开始创建模板时,他们首先意识到的是他们需要一种管理URL的方法。

  4. 计算复杂 - 它们由您的浏览器实现(希望根据RFC)。请参见RFC3986中的第5章。

  5. 糟糕的错误处理 - 错误或拼写错误可能导致蜘蛛陷阱。


路由的演变

开发人员已经停止以这里讨论的方式编写URL。所有请求都是针对网站的索引文件并包含查询字符串,也就是一个路由。可以将路由视为一个迷你URL,告诉应用程序要生成的内容。

<a href="<?=Route::url('named_url', array('first' => 'my', 'last' => 'whacky'))?>">
    http://dev.example.com/index.php/my:whacky:url
</a>

路由器优势:

  1. 具备绝对 URL 的所有优点。
  2. 允许 URL 包含任何字符。
  3. 更多控制权(有利于 SEO)。
  4. 能够通过算法生成 URL。这使得 URL 可配置。在单个文件中更改 URL 就可以完成 URL 的更改。
  5. 无需 404 错误页面。回退路由可以显示站点地图或错误页面。
  6. 间接访问应用程序文件的方便安全性。守卫语句可以确保每个人都是通过适当的渠道到达的。
  7. MVC 方法的实用性。

我的看法

大多数人在项目中以某种方式使用所有三种形式。关键是要理解它们,选择最适合任务的形式。


1
你缺少协议相对URL,这比完全绝对URL更好。在升级方案(主要是升级到HTTPS)时,绝对URL会引起麻烦,而相对URL可以解决这个问题。 - Tobu
@Tobu 只需通过 HTTPS 提供所有内容。 - None
顺便提一句:你在上面的大部分代码示例中使用了印刷引号。你可能需要修复它。 - domsson
那种以点号开头的URL是什么类型?例如:“./index.html” - Narvalex
你能详细解释一下“Clairvoyance”吗?如果你使用的是“根相对”URL,为什么不能看到人们在抓取你的网站? - Lovethenakedgun
1
@Lovethenakedgun 如果有人复制代码甚至将他们的域名指向您的服务器IP,相对URL将使用户停留在假网站上,而绝对URL将引导用户返回真实网站。绝对URL是对来源的归属。搜索引擎可以用来查找粗心的剪贴板或窃取内容或复制整个网站的欺诈者,例如钓鱼。 - None

12
我必须不同意大多数人的观点。
我认为相对URL方案在你想要快速启动并且不需要创新思维的情况下是“可以接受的”,特别是当你的项目规模较小,开发人员很少(或者只有你自己)。
然而,一旦你开始处理大型复杂系统,在不同域和协议之间频繁切换时,我认为更优雅的方法是必要的。
从本质上比较绝对URL和相对URL,绝对URL胜出。为什么呢?因为它永远不会出错。绝对URL就是它所说的那样。问题在于当你需要维护你的绝对URL时。
绝对URL链接的弱点是将整个URL硬编码。这不是一个好主意,可能是人们认为它们危险、邪恶和烦人的原因。更好的方法是编写一个易于使用的URL生成器。这些生成器很容易编写,并且可以非常强大——自动检测协议、易于配置(只需为整个应用程序设置一次URL),并且自动插入您的域名。好处在于:您可以继续使用相对URL进行编码,而在运行时,应用程序会将URL动态地插入为完整的绝对URL。太棒了。
考虑到几乎所有现代网站都使用某种形式的动态后端,以这种方式进行操作符合该网站的最佳利益。绝对URL不仅可以确保链接指向正确,还可以提高SEO性能。
我要补充的是,认为绝对URL会改变页面加载时间的论点是错误的。如果你的域名比几个字节还要重,并且你使用的是上世纪80年代的拨号调制解调器,那么没错。但这种情况已经不再存在了。https://stackoverflow.com/只有25个字节,而他们用于导航区域的"topbar-sprite.png"文件超过9 KB。这意味着与精灵文件相比,额外的URL数据仅占加载数据的0.2%,而该文件甚至都不被认为是性能损失较大的因素。
那个庞大、未优化的全页背景图更有可能拖慢你的加载时间。
关于为什么不应该使用相对URL的有趣帖子在这里: 为什么相对URL应该被禁止使用于网页开发者 相对URL可能会引发问题,例如,有时服务器映射(特别是在大型混乱的项目中)与文件名不匹配,开发者可能会对相对URL做出错误的假设。我今天就在我参与的一个项目中看到了这种情况,结果整个页面都崩溃了。
或者可能是开发人员忘记切换指针,突然之间谷歌索引了你的整个测试环境。哎呀-重复内容(对于SEO来说不好!)。
绝对可以是危险的,但是当正确使用并且以一种“不会破坏你的构建”的方式时,它们被证明更可靠。看看上面的文章,它列举了许多原因,解释了为什么WordPress的URL生成器非常棒。
:)

1
当你说绝对URL时,是指完整的URL还是使用“/”链接到基本路径?例如/products/wallets/thing.htmlthing.html相比,又与http://www.myshop.com/products/wallets/thing.html相比。 - Bradley Flood
这是目前的最佳实践,尽管许多人还没有意识到。我喜欢路由,比如在Kohana中,您可以使用echo Route::url('route_name')来构建绝对URL,使用站点URL和路由信息,并选择通过HTTPS进行访问。 - None
生成与否与URL类型无关。您正在为生成辩论,但用户代理无论生成的URL是否是绝对的都不会在意。 - Tobu
我并不是为了任何其他原因而主张生成,只是因为自动化使生活更轻松。我当然不是说UA会知道区别。 - dudewad
在我看来,链接的文章和你回答的大部分内容都在说“相对URL不好是因为SEO”。然而,从技术角度来看,我并没有看到任何问题。更重要的是,我不认为依赖工具或CMS机制来维护我的URL有什么优点——特别是如果主要是为了SEO。对我来说,简单总是胜过复杂,这意味着相对URL在任何时候都比绝对URL更好。 - domsson
显示剩余4条评论

6
如果是用于您的网站内部使用,最好使用相对URL,像这样。如果您需要将网站移动到另一个域名或者只是在本地进行调试,您可以这样做。
看一下Stack Overflow正在做什么(在Firefox中按Ctrl + U):
<a href="/users/recent/90691"> // Link to an internal element

在某些情况下,他们使用绝对URL:
<link rel="stylesheet" href="http://sstatic.net/so/all.css?v=5934">

...但这只是一种提高速度的最佳实践。就你的情况来看,似乎并没有做类似的事情,所以我不会担心这个问题。

4

在大多数情况下,相对URL是更好的选择,它们具有可移植性,这意味着如果您想将您的网站移到其他地方,它会立即工作,从而减少可能长达数小时的调试时间。

关于绝对URL和相对URL,这里有一篇相当不错的文章,可以看看。


4

以URL方案和特定于方案的部分(http://https://ftp://等)开头的URL是绝对URL。

任何其他URL都是相对URL,并且需要一个基本URL来解析相对URL(因此依赖于)该引用所使用的资源的URL,如果没有声明,则为该引用所使用的资源的URL。

请参阅RFC 2396 - 附录C,了解解析相对URL的示例。


3

假设你有一个网站www.yourserver.example。在网页文件的根目录下,你有一个名为images的子目录,在其中又有一个名为myimage.jpg的文件。

绝对URL定义了文档的确切位置,例如:

http://www.yourserver.example/images/myimage.jpg

相对URL是相对于当前目录的位置定义,例如,假设您在根网络目录中,您的图像位于:

images/myimage.jpg

(相对于根目录)

在可能的情况下,您应该始终使用相对URL。如果您将站点移动到www.anotherserver.com,则必须更新所有指向www.yourserver.example的绝对URL,而相对URL将保持不变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接