URL(统一资源定位符)是因特网中的唯一资源的地址。它是浏览器用于检索已发布资源(例如 HTML 页面、CSS 文档、图像等)的关键机制之一。
理论上说,每个有效的 URL 都指向一个唯一的资源。
例子:
https://www.example.com:443/docs/tutorial/index.html?lang=zh&page=1#chapter1
| 部分 | 例子 | 功能说明 |
|---|---|---|
| 协议 | https:// | 规定使用哪种协议访问资源。常见的有 http、https(加密的HTTP)、ftp等。浏览器和服务器根据协议来通信。://是固定分隔符。 |
| 主机名 | www.example.com | 指定资源所在的服务器。通常是一个域名,也可以直接使用IP地址。 |
| 端口 | :443 | 指定连接到服务器上的哪个网络服务。https 的默认端口是 443,http 是 80。因为默认,所以这个部分通常被省略。 |
| 路径 | /docs/tutorial/index.html | 表示资源在服务器上的具体位置,就像电脑上的文件路径一样。它指向一个具体的页面、图片或文件。 |
| 查询参数 | ?lang=zh&page=1 | 在 ? 之后,用于向服务器提供额外参数。格式是 键=值,多个参数用 & 连接。例如,这个URL告诉服务器:需要中文版本,并且跳转到第一页。 |
| 锚点 | #chapter1 | 在 # 之后,它不会发送给服务器。其作用是让浏览器直接跳转到页面内的某个特定位置(如一个标题或章节)。 |
绝对URL提供了资源的完整路径,包含了访问该资源所需的所有部分。
结构:协议://主机名:端口/路径?查询参数#锚点
示例:
https://www.example.com/images/logo.png
https://blog.example.com/articles/index.html
//cdn.example.com/script.js (这是一种特殊的协议相对URL,它会继承当前页面的协议(HTTP或HTTPS),现在已不推荐使用)。
特点与用法:
独立性:它不依赖于任何上下文,可以在任何地方使用——无论是另一个网站、电子邮件、文档或二维码——都能准确定位到资源。
用于外部资源:当你的网站需要链接到另一个域名下的资源时,必须使用绝对URL。
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<a href="https://twitter.com/your_profile">关注我们</a>
相对URL只提供了资源的部分路径,它需要与当前页面的基础URL结合起来,才能形成完整的地址。
基础URL(Base URL):通常是当前正在浏览的网页的URL。
相对URL主要有以下几种形式:
以 斜杠 / 开头。它表示从网站的根域名开始计算路径。
不以斜杠开头。它表示从当前页面所在的目录开始计算路径。
使用 ../ 来表示“向上移动一级目录”。
语义URL,也称为语义化URL或友好URL,指的是其路径和结构能够清晰地向人类和机器(如搜索引擎)传达页面内容主题的URL。
简单来说,就是“一看就懂”的网址。
一个良好的语义URL通常包含与页面内容相关的关键词,并使用易于理解的单词和逻辑结构。
可读性强、易于记忆和分享、可操作性强
避免使用动态参数:尽量将 ?id=123&category=abc 这样的参数重写为友好的路径形式。这通常需要通过服务器的 URL重写 功能(如Apache的 mod_rewrite 或Nginx的 rewrite 规则)来实现。
使用小写字母:统一使用小写字母可以避免因大小写混淆而导致的访问错误(有些服务器系统是大小写敏感的)。
非语义URL通常是由动态网站(如PHP、Python、Java等)生成的。要将其变为语义URL,需要进行 URL重写。
原理:服务器端通过规则,将用户看到的“友好URL”在内部映射到处理该请求的真实脚本和参数。
示例(Apache的 .htaccess 文件):
# 将 "example.com/product.php?id=123" 重写为 "example.com/product/123"
RewriteEngine On
RewriteRule ^product/([0-9]+)/?$ product.php?id=$1 [L]
# 更高级的例子:将 "example.com/articles/how-to-bake-a-cake" 映射到 "example.com/article.php?slug=how-to-bake-a-cake"
RewriteRule ^articles/([a-zA-Z0-9-]+)/?$ article.php?slug=$1 [L]
示例Nginx:
目标:
将用户访问的友好URL:https://example.com/product/123
在内部映射到:/product.php?id=123
server {
listen 80;
server_name example.com;
# 定义网站的根目录
root /var/www/html;
index index.php index.html index.htm;
# 位置块用于匹配 product/ 后跟一个数字的URL
location ~ ^/product/(\d+)/?$ {
# 将请求重写到 product.php,并传递 id 参数
# $1 代表前面正则表达式捕获的第一个分组,即 (\d+)
try_files $uri $uri/ /product.php?id=$1;
}
# 处理PHP文件的配置
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
# 非常重要:告诉PHP脚本实际要执行的文件名
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
使用 try_files 实现「前端控制器」模式(最常用于现代框架)
server {
listen 80;
server_name example.com;
root /var/www/laravel/public; # 注意:根目录指向了 public 文件夹
index index.php index.html;
# 处理所有请求
location / {
# 首先尝试将请求作为文件或目录处理;
# 如果找不到,则重写URL,将请求发送到 index.php
# $query_string 用于保留原始的GET参数
try_files $uri $uri/ /index.php?$query_string;
}
# 处理PHP文件
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
# 防止执行不存在的PHP文件
try_files $uri =404;
}
# 禁止访问 .htaccess 或其他隐藏文件
location ~ /\.(?!well-known).* {
deny all;
}
}
现代Web框架(如 Django, Ruby on Rails, Laravel, Express.js 等)都内置了非常便捷的路由功能,可以让你轻松地定义出语义化的URL结构,而无需手动配置复杂的重写规则。