ToolDeck

Phân tích URL

Phân tích URL thành các thành phần — giao thức, host, đường dẫn, tham số truy vấn, hash

Thử ví dụ

Phân tích URL là gì?

Phân tích URL là quá trình tách một Uniform Resource Locator thành các thành phần riêng lẻ: giao thức (scheme), hostname, port, pathname, tham số truy vấn và định danh fragment. Mọi URL đều tuân theo cấu trúc được định nghĩa bởi RFC 3986 và WHATWG URL Standard. Bộ phân tích URL đọc chuỗi thô, xác định từng đoạn dựa vào các ký tự phân cách (://, :, /, ?, #, &, =) và trả về chúng dưới dạng các trường riêng biệt, có thể truy cập độc lập.

Trình duyệt thực hiện phân tích URL mỗi khi bạn nhập địa chỉ hoặc nhấp vào một liên kết. Hàm khởi tạo URL trong JavaScript, mô-đun urllib.parse của Python và gói net/url của Go đều triển khai bộ phân tích tuân theo cùng các quy tắc cấu trúc. Phân tích URL là phép nghịch đảo của mã hóa URL: thay vì chuyển đổi ký tự để truyền tải an toàn, bạn tách một URL đã được hình thành thành các phần cấu thành nó.

Một URL điển hình như https://api.example.com:8080/v1/users?page=2&limit=10#section chứa sáu thành phần riêng biệt. Các ký tự phân cách — ://, :, /, ?, &, =, và # — là yếu tố làm cho việc phân tích trở nên xác định: mỗi ký tự báo hiệu một ranh giới và cho phép bộ phân tích trích xuất các trường mà không có sự mơ hồ.

Tại sao sử dụng công cụ phân tích URL trực tuyến?

Tách URL bằng mắt thường dễ xảy ra lỗi, đặc biệt khi chuỗi chứa các ký tự được mã hóa, nhiều tham số truy vấn hoặc các cổng không tiêu chuẩn. Công cụ này phân tích URL bằng cùng thuật toán tuân thủ WHATWG mà trình duyệt sử dụng và hiển thị từng thành phần trong một bảng rõ ràng, có thể sao chép.

Phân tích tức thì trong trình duyệt
Dán bất kỳ URL nào và xem ngay tất cả các thành phần được tách ra. Không tải lại trang, không gọi máy chủ, không chờ đợi.
🔒
Giữ URL của bạn riêng tư
Quá trình phân tích chạy hoàn toàn trong trình duyệt của bạn bằng API URL gốc. URL bạn nhập không bao giờ rời khỏi máy của bạn.
🔍
Kiểm tra từng chi tiết
Xem giao thức, hostname, port, pathname, chuỗi truy vấn, hash và từng tham số truy vấn riêng lẻ cùng giá trị đã được giải mã.
📋
Sao chép từng thành phần riêng lẻ
Nhấp vào nút sao chép bên cạnh bất kỳ trường nào để lấy giá trị chính xác. Không cần chọn và cắt bỏ chuỗi con thủ công.

Các trường hợp sử dụng công cụ phân tích URL

Gỡ lỗi định tuyến frontend
Kiểm tra xem các đoạn đường dẫn và fragment hash có khớp với cấu hình router của bạn không. Phát hiện các dấu gạch chéo bị đặt sai hoặc tham số truy vấn không mong muốn trước khi chúng gây ra lỗi 404.
Xác thực endpoint API backend
Xác minh rằng URL yêu cầu đến chứa đúng hostname, port và cấu trúc đường dẫn trước khi viết route handler hoặc middleware.
Kiểm thử quy tắc redirect DevOps
Khi viết quy tắc redirect cho Nginx, Apache hoặc CDN, hãy phân tích URL gốc và URL đích để xác nhận từng thành phần được ánh xạ đúng.
Xác minh liên kết trong QA
Phân tích URL từ báo cáo kiểm thử hoặc ticket lỗi để xác định tham số truy vấn hoặc fragment nào đang khiến trang sai được tải.
Trích xuất URL trong pipeline dữ liệu
Trích xuất hostname hoặc đoạn đường dẫn từ URL trong file log hoặc dữ liệu phân tích để xây dựng báo cáo cấp domain hoặc lọc lưu lượng theo endpoint.
Học cấu trúc URL
Sinh viên và lập trình viên mới làm quen với giao thức web có thể dán URL thực tế và xem ngay ký tự phân cách nào đánh dấu ranh giới nào.

Tham chiếu thành phần URL

Bảng dưới đây hiển thị mọi thuộc tính được trả về bởi hàm khởi tạo URL trong JavaScript khi phân tích URL. Các thành phần tương tự tồn tại trong kết quả urlparse của Python, struct url.URL của Go và đầu ra parse_url của PHP, mặc dù tên thuộc tính khác nhau giữa các ngôn ngữ.

Thuộc tínhVí dụMô tả
protocolhttps:Scheme including the trailing colon
hostnameapi.example.comDomain name or IP address
port8080Port number (empty string if default)
pathname/v1/usersPath starting with /
search?page=2&limit=10Query string including the leading ?
hash#sectionFragment identifier including the leading #
originhttps://api.example.com:8080protocol + hostname + port
hostapi.example.com:8080hostname + port
usernameadminCredentials before @ (rarely used in practice)
passwordsecretCredentials before @ (avoid in production URLs)
href(full URL)The complete, serialized URL string

WHATWG URL Standard so với RFC 3986

Hai đặc tả định nghĩa cách URL nên được phân tích. Chúng đồng ý về cấu trúc cơ bản nhưng khác nhau ở các trường hợp ngoại lệ — và sự khác biệt đó thường là nguyên nhân khi trình duyệt xử lý URL khác với máy chủ của bạn.

WHATWG URL Standard
Được sử dụng bởi tất cả trình duyệt hiện đại và hàm khởi tạo URL trong JavaScript. Chấp nhận và chuẩn hóa đầu vào không chặt chẽ: thiếu scheme, dấu gạch chéo ngược làm ký tự phân cách đường dẫn, tên miền quốc tế thông qua Punycode. Được định nghĩa là tiêu chuẩn sống tại url.spec.whatwg.org.
RFC 3986
Đặc tả IETF chính thức (2005). Nghiêm ngặt hơn WHATWG: từ chối một số đầu vào mà trình duyệt chấp nhận. Được sử dụng bởi nhiều thư viện phía máy chủ bao gồm net/url của Go và urllib.parse của Python. Được định nghĩa trong RFC 3986.

Trong thực tế, hầu hết sự khác biệt xuất hiện khi phân tích URL có tên miền quốc tế (IDN), thiếu scheme hoặc ký tự bất thường. Bộ phân tích WHATWG tự động chuyển đổi hostname IDN sang Punycode, trong khi bộ phân tích RFC 3986 nghiêm ngặt có thể từ chối chúng. Nếu bạn dán URL vào công cụ này và thấy kết quả khác với code phía máy chủ tạo ra, thì sự khác biệt giữa WHATWG và RFC rất có thể là nguyên nhân.

Ví dụ code

Mọi ngôn ngữ lớn đều có bộ phân tích URL tích hợp sẵn. Các ví dụ dưới đây phân tích cùng một URL và trích xuất các thành phần của nó. Lưu ý sự khác biệt nhỏ về tên gọi giữa các ngôn ngữ: Python dùng scheme thay vì protocol, và Go dùng RawQuery thay vì search.

JavaScript (browser / Node.js)
const url = new URL('https://api.example.com:8080/v1/users?page=2&limit=10#section')

url.protocol  // → "https:"
url.hostname  // → "api.example.com"
url.port      // → "8080"
url.pathname  // → "/v1/users"
url.search    // → "?page=2&limit=10"
url.hash      // → "#section"

// Iterate over query parameters
for (const [key, value] of url.searchParams) {
  console.log(`${key} = ${value}`)
}
// → "page = 2"
// → "limit = 10"

// Modify and re-serialize
url.searchParams.set('page', '3')
url.toString()
// → "https://api.example.com:8080/v1/users?page=3&limit=10#section"
Python
from urllib.parse import urlparse, parse_qs

result = urlparse('https://api.example.com:8080/v1/users?page=2&limit=10#section')

result.scheme    # → 'https'
result.hostname  # → 'api.example.com'
result.port      # → 8080
result.path      # → '/v1/users'
result.query     # → 'page=2&limit=10'
result.fragment  # → 'section'

# Parse query string into a dict
params = parse_qs(result.query)
params['page']   # → ['2']
params['limit']  # → ['10']

# Reconstruct with modifications
from urllib.parse import urlencode, urlunparse
new_query = urlencode({'page': '3', 'limit': '10'})
urlunparse(result._replace(query=new_query))
# → 'https://api.example.com:8080/v1/users?page=3&limit=10#section'
Go
package main

import (
	"fmt"
	"net/url"
)

func main() {
	u, err := url.Parse("https://api.example.com:8080/v1/users?page=2&limit=10#section")
	if err != nil {
		panic(err)
	}

	fmt.Println(u.Scheme)   // → "https"
	fmt.Println(u.Hostname()) // → "api.example.com"
	fmt.Println(u.Port())     // → "8080"
	fmt.Println(u.Path)       // → "/v1/users"
	fmt.Println(u.RawQuery)   // → "page=2&limit=10"
	fmt.Println(u.Fragment)   // → "section"

	// Query params as map
	q := u.Query()
	fmt.Println(q.Get("page"))  // → "2"
	fmt.Println(q.Get("limit")) // → "10"
}
PHP
<?php
$url = 'https://api.example.com:8080/v1/users?page=2&limit=10#section';
$parts = parse_url($url);

$parts['scheme'];   // → "https"
$parts['host'];     // → "api.example.com"
$parts['port'];     // → 8080
$parts['path'];     // → "/v1/users"
$parts['query'];    // → "page=2&limit=10"
$parts['fragment']; // → "section"

// Parse query string into an array
parse_str($parts['query'], $params);
$params['page'];    // → "2"
$params['limit'];   // → "10"

Câu hỏi thường gặp

Sự khác nhau giữa URL và URI là gì?
URL (Uniform Resource Locator) là một loại URI (Uniform Resource Identifier) cụ thể bao gồm cả định danh lẫn cơ chế truy cập (scheme, như https://). Mọi URL đều là URI, nhưng không phải mọi URI đều là URL. Một URN như urn:isbn:0451450523 là URI xác định tài nguyên theo tên mà không chỉ định cách truy xuất nó. Trong phát triển web, hai thuật ngữ thường được dùng thay thế cho nhau vì hầu hết mọi URI bạn gặp đều là URL.
Hàm khởi tạo URL xử lý URL tương đối như thế nào?
Hàm khởi tạo URL trong JavaScript yêu cầu một URL cơ sở khi phân tích đường dẫn tương đối. Gọi new URL('/path?q=1') sẽ ném TypeError. Bạn phải cung cấp base: new URL('/path?q=1', 'https://example.com'). urljoin của Python và url.ResolveReference của Go phục vụ cùng mục đích. Công cụ này yêu cầu URL đầy đủ, tuyệt đối có scheme.
Điều gì xảy ra khi URL không có số cổng?
Khi port bị bỏ qua, bộ phân tích trả về chuỗi rỗng cho thuộc tính port. Trình duyệt giả định cổng mặc định cho scheme: 443 cho https, 80 cho http, 21 cho ftp. Bạn có thể truy cập cổng thực tế thông qua thuộc tính origin hoặc host, nhưng trường port tự nó vẫn rỗng vì không có cổng tường minh nào được chỉ định.
URL có thể chứa ký tự Unicode không?
Có, nhưng chúng phải được mã hóa để truyền tải. WHATWG URL Standard xử lý điều này tự động: tên miền quốc tế được chuyển đổi sang Punycode (tiền tố xn--), và các ký tự đường dẫn/truy vấn ngoài phạm vi ASCII được mã hóa phần trăm. Nếu bạn dán URL có Unicode vào công cụ này, bạn sẽ thấy phiên bản đã chuẩn hóa, an toàn ASCII trong kết quả phân tích.
Độ dài tối đa của URL là bao nhiêu?
Không có tiêu chuẩn nào định nghĩa độ dài URL tối đa — RFC 3986 không đề cập đến vấn đề này. Trên thực tế, trình duyệt áp đặt giới hạn: Chrome hỗ trợ tới khoảng 2MB trong thanh địa chỉ, trong khi Internet Explorer (cũ) có giới hạn 2.083 ký tự. Hầu hết máy chủ web mặc định là 8KB (Nginx) hoặc 8KB (Apache) cho dòng yêu cầu. Nếu cần truyền dữ liệu lớn, hãy dùng body của yêu cầu POST thay vì chuỗi truy vấn.
Làm cách nào để phân tích chỉ chuỗi truy vấn mà không cần URL đầy đủ?
Trong JavaScript, dùng new URLSearchParams('page=2&limit=10') để phân tích chuỗi truy vấn thuần túy. Trong Python, dùng urllib.parse.parse_qs('page=2&limit=10'). Cả hai đều trả về các tham số dưới dạng cặp khóa-giá trị. Điều này hữu ích khi bạn chỉ có chuỗi truy vấn riêng lẻ, ví dụ từ một lần gửi form hoặc một mục log chỉ ghi lại phần truy vấn.
Phân tích URL có giống với giải mã URL không?
Không. Phân tích URL tách URL thành các thành phần cấu trúc (scheme, host, path, query, fragment). Giải mã URL chuyển đổi các ký tự mã hóa phần trăm trở lại dạng gốc (%20 thành dấu cách, %26 thành &). Hai thao tác này bổ sung cho nhau: thông thường bạn phân tích URL trước, rồi giải mã các giá trị thành phần riêng lẻ. Giải mã trước khi phân tích có thể phá vỡ cấu trúc URL vì các ký tự phân cách đã giải mã như & và = sẽ bị hiểu sai.