Nhân việc cuối tuần mà lại bị giãn cách xã hội, chán nên mình làm một công cụ miễn phí giúp các lập trình viên truy cập dữ liệu chuẩn về danh sách các địa phương, mã số, mã vùng điện thoại, với hi vọng các ứng dụng liên quan đến Việt Nam (ngân hàng, giao nhận, vận tải, truyền thông v.v…) sẽ sử dụng thống nhất một nguồn dữ liệu (ban hành bởi Nhà nước), để thuận lợi hơn cho việc trao đổi hợp tác.
Online API lấy danh sách tỉnh thành quận huyện Việt Nam
Ngon quá. Cám ơn bạn nhé
Lấy toàn bộ và lấy riêng từng cấp theo mã số. Rất hay! Mong bạn giữ dữ liệu luôn được cập nhật mới nhất.
- Nhưng thử phần truy vấn riêng từng cấp đơn vị thì không được cho cả 3 cấp
api/p
,api/d
vàapi/w
. - Truy vấn ở tham số
depth=3
(https://provinces.open-api.vn/api/?depth=3
) thì máy chủ “tèo” luôn.
Cảm ơn bạn đã test. Mình vừa sửa lỗi ở depth=3
.
Về các endpoint /ap/p
, api/d
, api/w
thì ban đầu mình định không sử dụng, nhưng có lẽ người dùng sẽ dùng nó thật, sẽ bổ sung.
Nên có api lấy từng đơn vị lẻ, giả sử mình chỉ muốn lấy các xã (tương đương)trong 1 huyện (tương đương), chả lẽ lại phải gọi đến api depth=3 để lấy, tốn dữ liệu lắm.
Bạn đọc không kĩ tài liệu rồi. Trường hợp của bạn, gọi GET /api/d/{code}
là ra thôi.
Cám ơn bạn, đã sửa. Hơi bị lúng túng với cách cấu hình của bọn Vercel.
Đây là ví dụ lấy danh sách các xã ở huyện quê mình: https://provinces.open-api.vn/api/d/754?depth=2
Bác cho e hỏi cái hàm function markRequireAll ở trên có chức năng gì vậy ạ,
và nếu k dùng nó thì param q ở đây giá trị là gì vậy ạ?
function markRequireAll(query) {
const words = query.split(/\s+/)
return words.map(w => `+${w}`).join(' ')
}
async function searchProvince(term, app) {
if (app.selectedProvince && app.selectedProvince.name === term) {
return
}
const rdata = await ky.get('/api/p/search/', {
searchParams: { q: markRequireAll(term) }
}).json()
app.filteredProvinces = mask(rdata, array(Province))
}
Có cái comment ngay phía đầu hàm để giải thích mà bạn copy kiểu gì cũng phải cắt nó ra là sao nhỉ?
/*
* The Lunr engine consider each keyword optional, but in the context of
* this demo, we want all keywords to be present
*/
function markRequireAll(query) {
const words = query.split(/\s+/)
return words.map(w => `+${w}`).join(' ')
}
Nó đơn giản là thêm dấu “+” vào trước từng từ trong chuỗi thôi, “Bà Rịa” -> “+Bà +Rịa”.
q
đơn giản là cụm từ bạn muốn tìm kiếm thôi.
dạ tại e đang k biết bên anh dùng thư viện gì để nối các params thành url, với cả cũng k rõ thuật toán tìm kiếm bên anh, nên mới k rõ nó tại sao phải thêm dấu + vào trc từng từ ạ
Đâu có cần nối gì đâu? Tự thư viện HTTP client lo chuyện đó. Còn mình dùng thư viện nào để request HTTP thì nó nằm sát bên dòng code bạn đang đọc.
const rdata = await ky.get('/api/d/search/', {
searchParams: { q: markRequireAll(term), p: provinceCode }
}).json()
Bạn đang đọc tới chỗ “q: markRequireAll(term)
” thì liếc ngay lên dòng phía trên là thấy tên thư viện đang dùng rồi: “ky.get()
”
Comment nói mục đích của việc thêm dấu “+” rồi:
The Lunr engine consider each keyword optional, but in the context of this demo, we want all keywords to be present.
Biến từ “optional” thành “required” thôi.
mình muốn lấy tới thôn xóm thì sao ad?
Dữ liệu đó không có, nếu có thì đã viết vào tài liệu, chứ mắc gì hướng dẫn lấy đến 3 cấp rồi tự dưng lại bỏ thôn xóm ra?
Mình cũng bị như thế…
Mình dùng VueJS để call API mà dính lỗi CORS thì phải làm sao ạ. Mình cảm ơn!
Vụ CORS thì các bạn phải tự tìm cách theo dõi được request “preflight” mà trình duyệt gửi đi, xem nó có kết quả gì.
Bên mình thì không tái hiện được lỗi CORS này. Mình có một demo khác cho VueJS (Vue 3 + TypeScript) ở đây: https://github.com/hongquan/vn-provinces-vue-demo
Nó được triển khai trên một website riêng để kiểm chứng là không có lỗi CORS.