Một số nghiệp vụ không cần “chặn truy cập”, mà cần “phân luồng theo vùng” nhẹ hơn: trên cùng một trang, người dùng đến từ các quốc gia/khu vực khác nhau khi bấm vào liên kết hoặc nút bấm thì phải đi đến các URL đích khác nhau. Kiểu phân luồng này thường dùng cho: phân phối URL tải xuống, cổng thanh toán theo vùng, hệ thống CSKH khác nhau, chuyển đổi lối vào các site khác nhau (quốc tế/nội địa), v.v.
Bài viết này chỉ nói một điểm cốt lõi: khi trang tải, frontend gửi GET https://my.ipin.io/info để lấy mã quốc gia country của người truy cập,
sau đó đặt href của thẻ <a> hoặc URL điều hướng khi bấm <button> thành URL tương ứng với khu vực.
Ví dụ API có thể trả về:
{"ip":"185.220.236.7","country":"TW","region":"Taiwan","city":"Taipei"}
1)Logic và nguyên lý hoạt động(2 đoạn)
Đoạn 1: luồng xử lý
Trang tải → frontend lập tức gọi https://my.ipin.io/info → lấy country → chọn URL đích theo quy tắc của bạn (ví dụ TW dùng URL A 1, US dùng URL A 2, các vùng khác dùng URL mặc định) →
cập nhật “đích đến” của liên kết hoặc nút bấm thành URL đích đó. Khi người dùng bấm, họ mới đi đến đúng địa chỉ tương ứng.
Đoạn 2: vì sao nên đặt URL mặc định trước rồi ghi đè theo vùng
Môi trường frontend không ổn định tuyệt đối: mạng, CORS, tiện ích chặn quảng cáo, timeout của API đều có thể khiến bạn không lấy được country. Cách làm ổn định hơn là:
trên trang luôn có sẵn một URL mặc định dùng được (landing chung), khi script lấy được vùng thành công thì mới ghi đè sang URL theo vùng. Như vậy dù API lỗi, trang vẫn điều hướng bình thường, tránh tình trạng “bấm không phản hồi/địa chỉ rỗng”.
2)Triển khai code(siêu đơn giản, tách riêng A và button)
2.1 Liên kết A(dùng id):đặt href theo country
Tình huống: trang chỉ có một liên kết quan trọng, bạn muốn nó trỏ đến các địa chỉ khác nhau theo vùng. Ví dụ dưới đây chỉ minh hoạ logic tối giản:
nếu là TW thì dùng link TW, còn lại dùng link mặc định.
<a id="geoLink" href="https://example.com/default">Đi ngay</a>
<script>
(async function () {
try {
const info = await fetch("https://my.ipin.io/info").then(r => r.json());
const target = (info.country === "TW")
? "https://example.com/tw"
: "https://example.com/default";
const a = document.getElementById("geoLink");
if (a) a.href = target;
} catch (e) {
// Lỗi thì giữ href mặc định
}
})();
</script>
2.2 Liên kết A(dùng class):cập nhật href hàng loạt theo country
Tình huống: trang có nhiều liên kết đều cần phân luồng theo vùng. Cách đơn giản nhất là: gán cùng một class rồi cập nhật đồng loạt. Ví dụ vẫn giữ tối giản: TW dùng link TW, các vùng khác dùng link mặc định.
<a class="geo-link" href="https://example.com/default">Cổng tải xuống</a>
<a class="geo-link" href="https://example.com/default">Cổng mua hàng</a>
<script>
(async function () {
try {
const info = await fetch("https://my.ipin.io/info").then(r => r.json());
const target = (info.country === "TW")
? "https://example.com/tw"
: "https://example.com/default";
document.querySelectorAll(".geo-link").forEach(function (el) {
el.href = target;
});
} catch (e) {}
})();
</script>
2.3 Button(dùng id):bấm rồi điều hướng theo country
Tình huống: button không phải là liên kết trực tiếp, nên bạn cần gắn sự kiện click ở frontend. Ví dụ dưới đây chỉ giữ logic cốt lõi: chọn URL đích theo country trước, rồi khi bấm nút thì điều hướng đến URL đó.
<button id="geoBtn" type="button">Bấm để chuyển trang</button>
<script>
(async function () {
let target = "https://example.com/default"; // URL mặc định
try {
const info = await fetch("https://my.ipin.io/info").then(r => r.json());
if (info.country === "TW") target = "https://example.com/tw";
} catch (e) {
// Lỗi thì dùng URL mặc định
}
const btn = document.getElementById("geoBtn");
if (btn) btn.onclick = function () { window.location.href = target; };
})();
</script>
2.4 Button(dùng class):gắn click điều hướng hàng loạt
Tình huống: trang có nhiều button đều cần điều hướng theo vùng. Cách đơn giản nhất: dùng class chung rồi vòng lặp để gắn sự kiện click. Lưu ý: button không có “href mặc định”, vì vậy nên chuẩn bị sẵn một URL mặc định trong script để tránh trường hợp API lỗi khiến button “bấm không phản hồi”.
<button class="geo-btn" type="button">Nút 1</button>
<button class="geo-btn" type="button">Nút 2</button>
<script>
(async function () {
let target = "https://example.com/default"; // URL mặc định
try {
const info = await fetch("https://my.ipin.io/info").then(r => r.json());
if (info.country === "TW") target = "https://example.com/tw";
} catch (e) {}
document.querySelectorAll(".geo-btn").forEach(function (btn) {
btn.onclick = function () { window.location.href = target; };
});
})();
</script>
2.5 Nhiều khu vực(TW、US…):dùng bảng mapping để “thiết lập URL đích trực tiếp” (ngắn nhất dùng được)
Quy tắc đơn giản nhất: chuẩn bị URL mặc định trước, sau đó ghi đè bằng bảng mapping map theo mã quốc gia.
Có mapping thì dùng mapping, không có thì dùng mặc định. Điểm mấu chốt: tính ra target xong phải áp vào href của A hoặc sự kiện click của button ngay lập tức.
2.5.1 Dùng cho A link(id):đặt href trực tiếp
<a id="geoLink" href="https://example.com/default">Đi ngay</a>
<script>
(async function () {
const defaultUrl = "https://example.com/default";
const map = { TW: "https://example.com/tw", US: "https://example.com/us" };
try {
const info = await fetch("https://my.ipin.io/info").then(r => r.json());
const target = map[info.country] || defaultUrl;
document.getElementById("geoLink").href = target; // ✅ Mấu chốt: ghi target vào href
} catch (e) {
// Lỗi thì giữ href mặc định
}
})();
</script>
2.5.2 Dùng cho button(id):bấm thì chuyển đến target
<button id="geoBtn" type="button">Bấm để chuyển trang</button>
<script>
(async function () {
const defaultUrl = "https://example.com/default";
const map = { TW: "https://example.com/tw", US: "https://example.com/us" };
let target = defaultUrl;
try {
const info = await fetch("https://my.ipin.io/info").then(r => r.json());
target = map[info.country] || defaultUrl;
} catch (e) {}
document.getElementById("geoBtn").onclick = function () {
window.location.href = target; // ✅ Mấu chốt: bấm thì đi bằng target
};
})();
</script>
3)Triển khai trong WordPress / Joomla / Magento / Shopify…(cách làm frontend + code)
Với kiểu “đổi đích A link / đích điều hướng button theo vùng”, bản chất là đặt script vào phần Head dùng chung toàn site hoặc file layout để nó chạy càng sớm càng tốt. Bạn không cần chỉnh logic server; chỉ cần script chạy lúc trang tải là bạn đã chuẩn bị được đích đến trước khi người dùng bấm.
3.1 WordPress
- Dùng plugin “chèn script vào header/footer”, dán script vào Header(áp dụng toàn site)
- Hoặc chèn script trước
</head>trong file themeheader.php
3.2 Joomla! / Joomla
- Trong template hiện tại, tìm
<head>trongindex.phpvà dán script trước</head> - Hoặc dùng mục “custom head code” của template(tuỳ template sẽ khác nhau)
3.3 Magento
- Thêm script vào head global của theme(khu vực head trong theme/layout)
- Mục tiêu là xuất ra toàn site để bạn dễ quản lý quy tắc mapping theo vùng
3.4 Shopify
- Online Store → Themes → Edit code
- Tìm
theme.liquidvà dán script trước</head>(áp dụng toàn site)
3.5 Quy luật chung
- Hệ thống nào cho phép sửa
<head>dùng chung hoặc file layout đều có thể làm “thiết lập đích link/nút theo vùng IP” theo cách tương tự - Nên giữ URL mặc định để vẫn dùng được khi API bên ngoài gặp lỗi
4)Tóm tắt
> Khi trang tải, gọi https://my.ipin.io/info để lấy country, sau đó chọn URL đích theo country và lần lượt cập nhật href của A link hoặc địa chỉ điều hướng khi bấm button, từ đó реализ hiện方案 frontend “phân luồng theo vùng IP đến các đích khác nhau”.
Trong thực tế, hai điểm quan trọng nhất là: (1) đặt script càng sớm càng tốt trong head để chuẩn bị đích đến nhanh; (2) luôn có URL mặc định để tránh link vô hiệu hoặc button không phản hồi khi API lỗi. Chỉ cần bạn quản lý tốt quy tắc mapping theo vùng,方案 này sẽ chạy ổn cho cổng tải xuống, cổng thanh toán, cổng hỗ trợ, v.v.
5)Câu hỏi thường gặp
console.log(info) để xác nhận đã lấy được country hay chưa.
window.location.href = target thành window.open(target, "_blank"). Thường thì nếu gọi trong sự kiện click thì trình duyệt không chặn.
{ TW: "...", US: "..." }. Có match thì dùng URL tương ứng, không có thì dùng URL mặc định.
https://my.ipin.io/info thì bạn không lấy được country, cuối cùng chỉ có thể dùng URL mặc định. Trước khi上线 nên kiểm tra trên console xem request có成功 không.