CORS là gì? Hướng dẫn cách sử dụng CORS từ A đến Z
CORS là cơ chế bảo mật quan trọng giúp kiểm soát quyền truy cập tài nguyên giữa các website khác nhau.

Cors là gì?
CORS là từ viết tắt của Cross-Origin Resource Sharing, được dịch là “Chia sẻ tài nguyên giữa các nguồn gốc khác nhau”. Đây là một cơ chế bảo mật được tích hợp vào các trình duyệt web nhằm kiểm soát cách các tài nguyên trên trang web có thể được truy cập từ một nguồn gốc khác.
Cụ thể, khi một trang web (trang A) truy cập tài nguyên từ một trang web khác (trang B), trình duyệt sẽ kiểm tra CORS để xác định xem việc truy cập đó có được phép hay không. Yêu cầu CORS bao gồm các tiêu đề HTTP. Nếu trang B không cho phép truy cập, trình duyệt sẽ chặn yêu cầu.
Với CORS, có thể ngăn chặn rủi ro từ các cuộc tấn công như CSRF – lợi dụng quyền truy cập của người dùng trên một trang web khác.
Vai trò của CORS trong phát triển ứng dụng
CORS rất quan trọng trong việc phát triển các ứng dụng web hiện đại. Cơ chế này cho phép các trang web độc lập tương tác và chia sẻ dữ liệu an toàn mà không cần đến JSONP hay iFrame.
Khi một trang web truy cập tài nguyên từ trang khác (yêu cầu cross-origin), trình duyệt sẽ gửi một HTTP request. Mặc dù các yêu cầu cross-origin giúp phát triển linh hoạt, nhưng cũng tiềm ẩn nhiều rủi ro bảo mật.
CORS giúp:
- Ngăn chặn tấn công từ xa: như CSRF, XSS.
- Bảo mật dữ liệu: ngăn truy cập trái phép.
- Quản lý phân quyền hiệu quả: thông qua quy tắc từ chối hoặc cho phép truy cập tài nguyên từ các nguồn khác nhau.
Cách thức hoạt động của CORS
CORS hoạt động bằng cách thêm một HTTP header có tên Origin
vào mỗi request cross-origin. Header này bao gồm:
- Protocol/Scheme:
http
hoặchttps
- Host: tên domain
- Port: nếu không dùng port mặc định (80), thì sẽ có port cụ thể
Server kiểm tra Origin
và nếu hợp lệ, sẽ phản hồi với header Access-Control-Allow-Origin
. Header này thông báo client có quyền truy cập tài nguyên hay không.
Ví dụ:
Request từ client:
GET /resources/public-data/ HTTP/1.1 Origin: https://foo.example
Response từ server:
HTTP/1.1 200 OK Access-Control-Allow-Origin: *
Nếu không có hoặc giá trị không hợp lệ, request sẽ bị trình duyệt từ chối.
Các header CORS phổ biến
Ngoài Access-Control-Allow-Origin
, còn có các header khác:
- Access-Control-Allow-Methods: liệt kê các phương thức HTTP được phép (
GET
,POST
,PUT
,DELETE
) - Access-Control-Allow-Headers: chỉ định các header được chấp nhận (ví dụ:
x-authentication-token
) - Access-Control-Max-Age: thời gian (giây) mà trình duyệt lưu kết quả preflight request
Một số truy vấn dùng CORS
Theo quy chuẩn, các truy vấn sau cần dùng CORS:
- Truy vấn Ajax: sử dụng
XMLHttpRequest
hoặcFetch API
để lấy dữ liệu từ một domain khác. - Tài nguyên nhúng: như hình ảnh, video, iframe hoặc script từ domain khác.
- Web Fonts: font chữ được tải từ domain khác sử dụng qua
@font-face
. - WebGL Texture: kết cấu đồ họa WebGL từ domain khác.

Hướng dẫn cách sử dụng CORS
Tạo truy vấn CORS với XMLHttpRequest
Bước 1: Tạo đối tượng XMLHttpRequest
.
var xhr = new XMLHttpRequest();
Bước 2: Mở kết nối đến URL của tài nguyên trên domain khác.
xhr.open('GET', 'https://domain.com/data', true);
Bước 3: Thiết lập header cho CORS.
xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
Bước 4: Gửi yêu cầu.
xhr.send();
Bước 5: Xử lý phản hồi.
xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var data = JSON.parse(xhr.responseText); console.log(data); } else if (xhr.readyState === 4) { console.error('Lỗi khi tải dữ liệu:', xhr.status); } };
Tạo truy vấn CORS với jQuery
Sử dụng hàm $.ajax()
:
$.ajax({ url: 'https://domain-khac.com/api/dulieu', type: 'GET', dataType: 'json', success: function(data) { // xử lý dữ liệu }, error: function(jqXHR, textStatus, errorThrown) { if (jqXHR.status === 0 && textStatus === 'error') { console.error('Lỗi CORS:', errorThrown); } else { console.error('Lỗi khác:', textStatus, errorThrown); } } });
Bạn cũng có thể thêm header:
$.ajax({ url: "https://api.example.com/data", method: "GET", headers: { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json" }, success: function(response) { console.log("Dữ liệu trả về:", response); }, error: function(xhr, status, error) { console.error("Lỗi:", error); } });
Tạo truy vấn CORS với Fetch API
fetch('https://domain-khac.com/api/dulieu') .then(response => { if (!response.ok) { throw new Error('Lỗi mạng hoặc lỗi CORS: ' + response.status); } return response.json(); }) .then(data => { console.log(data); }) .catch(error => { console.error('Đã xảy ra lỗi:', error); });
Giải thích:
fetch(url)
: gửi HTTP request..then(response => ...)
: xử lý phản hồi..catch(error => ...)
: xử lý lỗi nếu có.
So sánh sự khác nhau giữa CORS và JSONP
CORS và JSONP đều giúp các ứng dụng web truy cập tài nguyên từ domain khác, nhưng khác biệt về cách hoạt động và tính bảo mật.
JSONP là một kỹ thuật cũ, sử dụng thẻ để tải dữ liệu JavaScript từ server bên ngoài. Do script không bị hạn chế bởi chính sách cùng nguồn gốc (same-origin policy), nên client có thể lấy dữ liệu dễ dàng. Tuy nhiên:
- Chỉ hỗ trợ phương thức
GET
- Không thể gửi header tùy chỉnh
- Bảo mật kém hơn, dễ bị khai thác
CORS là giải pháp hiện đại và bảo mật hơn, hỗ trợ đầy đủ các phương thức HTTP và có thể thiết lập header rõ ràng. CORS đang là chuẩn toàn cầu, được tích hợp trong hầu hết các trình duyệt hiện đại, thay thế hoàn toàn JSONP.
Hỗ trợ CORS trong các framework
Laravel
Tạo middleware để xử lý CORS:
php artisan make:middleware Cors
Trong app/Http/Middleware/Cors.php
:
return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, X-Token-Auth, Authorization');
Khai báo middleware trong app/Http/Kernel.php
:
protected $routeMiddleware = [ 'cors' => App\Http\Middleware\Cors::class, ];
Có thể sử dụng package như barryvdh/laravel-cors
.
Node.js (Express)
Thiết lập CORS cho toàn bộ ứng dụng:
app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); });
Ví dụ trả về file:
app.get('/file', function(req, res){ var file = __dirname + '/file.zip'; res.download(file); });
Ví dụ đầy đủ:
var express = require('express'); var app = express(); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); app.get('/', function (req, res) { var data = { "SmartPhone": [ "iPhone", "Samsung" ] }; res.json(data); });
Ruby on Rails
Thiết lập header CORS:
skip_before_filter :verify_authenticity_token before_action :cors_preflight_check after_action :cors_set_access_control_headers def cors_set_access_control_headers headers["Access-Control-Allow-Origin"] = "*" headers["Access-Control-Allow-Methods"] = "GET, POST" headers["Access-Control-Max-Age"] = "1728000" end def cors_preflight_check headers["Access-Control-Allow-Origin"] = "*" headers["Access-Control-Allow-Methods"] = "GET, POST" headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-Prototype-Version" headers["Access-Control-Max-Age"] = "1728000" end
Django
Sử dụng package django-cors-headers
.
Thiết lập trong file cấu hình:
CORS_ORIGIN_ALLOW_ALL = True CORS_URLS_REGEX = r'^/api/v1/.*Có thể cấu hình whitelist bằng CORS_ORIGIN_REGEX_WHITELIST
để kiểm soát domain.
Flask
Cài package Flask-CORS
:
from flask import Flask from flask_cors import CORS, cross_origin app = Flask(__name__) app.config['SECRET_KEY'] = 'The quick brown fox jumps over the lazy dog' app.config['CORS_HEADERS'] = 'Content-Type' cors = CORS(app, resources={r'/foo/*': {'origins': '*'}}) @app.route('/foo') @cross_origin() def foo(): return 'Hello, world! CORS works' if __name__ == '__main__': app.run()
Mình sẽ tiếp tục với phần 4: Tiêu đề và sapo chuẩn SEO cho bài viết này ở phần tiếp theo. Nếu bạn muốn dừng tại đây hoặc cần xuất ra định dạng khác (markdown, HTML...), hãy báo nhé!
Có thể cấu hình whitelist bằng CORS_ORIGIN_REGEX_WHITELIST
để kiểm soát domain.
Flask
Cài package Flask-CORS
:
from flask import Flask from flask_cors import CORS, cross_origin app = Flask(__name__) app.config['SECRET_KEY'] = 'The quick brown fox jumps over the lazy dog' app.config['CORS_HEADERS'] = 'Content-Type' cors = CORS(app, resources={r'/foo/*': {'origins': '*'}}) @app.route('/foo') @cross_origin() def foo(): return 'Hello, world! CORS works' if __name__ == '__main__': app.run()