django-tinymce: Ngăn đổi URL và ảnh Base64 trong HTMLField
django-tinymce mặc định đổi URL thành đường dẫn tương đối và lưu ảnh dán dưới dạng base64. Đây là cấu hình để ngăn cả hai khi lưu HTML.
Long Nguyen
Lập trình viên Fullstack · Kỹ sư AI · Nhà nghiên cứu
Khi lưu HTML có định dạng phong phú — chẳng hạn như mô tả sản phẩm — trong HTMLField của django-tinymce, hai hành vi mặc định của TinyMCE có thể âm thầm thay đổi nội dung: chuyển URL thành đường dẫn tương đối và nhúng ảnh được dán dưới dạng URI dữ liệu base64. Cả hai vấn đề đều có thể xử lý trong TINYMCE_DEFAULT_CONFIG, nhưng chỉ khi bạn hiểu chính xác thiết lập nào thực hiện việc đó.
Vấn đề 1: TinyMCE tự chuyển đổi URL
Theo mặc định, TinyMCE sẽ chuyển đổi URL trong nội dung. Một liên kết tuyệt đối bạn nhập là https://example.com/page có thể được trả về dưới dạng đường dẫn tương đối như ../../page. Liên kết sẽ hỏng ngay khi HTML đã lưu được hiển thị ở nơi khác với trang tạo nội dung — chẳng hạn một route khác, email, phản hồi API hoặc nguồn cấp dữ liệu.
Các thiết lập URL và thiết lập quan trọng nhất
Có ba thiết lập chi phối hành vi này và chúng hoạt động theo từng lớp — thứ tự rất quan trọng:
convert_urls(mặc định làtrue) là công tắc chính. Khi có giá trị true, TinyMCE sẽ thực hiện chuyển đổi URL. Khi là false, mọi URL được giữ nguyên chính xác như lúc nhập — không chuyển thành tương đối hay tuyệt đối.relative_urls(mặc định làtrue) chỉ có tác dụng khiconvert_urlslà true. Giá trị true khiến URL trở thành đường dẫn tương đối; false buộc URL ở dạng tuyệt đối.remove_script_host(mặc định làtrue) cũng chỉ áp dụng khi chuyển URL thành dạng tuyệt đối — thiết lập này kiểm soát việc có loại bỏ giao thức và máy chủ hay không.
Vì vậy, thiết lập quyết định là convert_urls: False. Chỉ cần đặt giá trị này, URL sẽ được giữ nguyên; khi đó relative_urls và remove_script_host không còn tác dụng. Nếu muốn tiếp tục bật chuyển đổi nhưng luôn tạo URL tuyệt đối với đầy đủ máy chủ, bạn sẽ giữ convert_urls: True và đặt relative_urls: False, remove_script_host: False. Đừng kỳ vọng chỉ relative_urls: False sẽ ngăn việc viết lại URL khi convert_urls vẫn là true và mục tiêu của bạn là không thay đổi URL nào — câu trả lời rõ ràng cho việc “giữ nguyên URL của tôi” là convert_urls: False.
TINYMCE_DEFAULT_CONFIG = {
# ... your other options ...
"convert_urls": False, # decisive: no URL rewriting at all
"relative_urls": False, # only relevant if convert_urls is True
"remove_script_host": False, # only relevant when producing absolute URLs
}
Vấn đề 2: ảnh được dán trở thành base64
Theo mặc định, khi bạn dán hoặc kéo trực tiếp một ảnh vào trình soạn thảo TinyMCE mà chưa cấu hình trình xử lý tải lên, TinyMCE sẽ nhúng ảnh ngay trong HTML dưới dạng URI dữ liệu base64. Mô tả vẫn hiển thị bình thường trong trình soạn thảo, nhưng mã đánh dấu đã lưu lúc này chứa toàn bộ ảnh được mã hóa thành văn bản.
Đây là một vấn đề thực sự với nội dung mô tả được lưu trữ: trường HTML phình to (một ảnh duy nhất có thể chiếm hàng trăm KB ở dạng base64), có thể chạm giới hạn cột cơ sở dữ liệu, làm chậm truy vấn và tải trang, khiến ảnh không thể được phân phối từ CDN hoặc lưu bộ nhớ đệm riêng, đồng thời bị nhân bản ở mọi nơi nội dung mô tả được sử dụng lại.
Cách ngăn việc nhúng ảnh base64
Cách xử lý là cung cấp cho TinyMCE một nơi để tải ảnh lên, để nó thay thế khối base64 bằng một URL thực:
- Cấu hình endpoint tải lên thông qua
images_upload_url(hoặcimages_upload_handlertùy chỉnh). Khiautomatic_uploadsđược bật (đây là mặc định), TinyMCE sẽ gửi khối ảnh đến endpoint của bạn và thay bằng URL được trả về thay vì base64. - Endpoint đó cần lưu tệp (vào vùng lưu trữ media hoặc object storage) và trả về URL công khai theo định dạng JSON mà TinyMCE yêu cầu (
{ "location": "https://..." }). - Nếu muốn từ chối hoàn toàn ảnh nội tuyến, hãy đặt
paste_data_images: Falseđể ảnh dán dưới dạng URI dữ liệu bị loại bỏ thay vì được nhúng.
Nguyên tắc đơn giản: nếu nội dung mô tả sẽ được lưu trữ và sử dụng lại, tuyệt đối không để ảnh tồn tại dưới dạng base64 — hãy đưa ảnh qua trình xử lý tải lên để trường dữ liệu chứa URL thay vì toàn bộ dữ liệu ảnh.
Đây là những thiết lập mặc định âm thầm nguy hiểm: chúng không tạo ra lỗi mà chỉ làm hỏng dữ liệu đã lưu cho đến khi một thành phần phía sau gặp sự cố. Tôi xây dựng và gỡ lỗi backend Django cùng các quy trình xử lý nội dung trong công việc của mình. Nếu bạn cần hỗ trợ về backend hoặc phần mềm tùy chỉnh, hãy xem dịch vụ của Netalith hoặc liên hệ trực tiếp với tôi qua LinkedIn.
CÂU HỎI THƯỜNG GẶP
Câu hỏi thường gặp
Thiết lập nào ngăn TinyMCE chuyển URL thành đường dẫn tương đối?
<code>convert_urls: False</code> là thiết lập quyết định — nó tắt toàn bộ việc chuyển đổi URL, vì vậy URL được giữ nguyên chính xác như lúc nhập. <code>relative_urls</code> và <code>remove_script_host</code> chỉ có tác dụng khi <code>convert_urls</code> là True.
Chỉ đặt <code>relative_urls: False</code> có ngăn được việc viết lại URL không?
Không hoàn toàn. <code>relative_urls</code> chỉ áp dụng khi <code>convert_urls</code> là True; trong trường hợp đó, giá trị False sẽ buộc URL ở dạng tuyệt đối. Để giữ URL hoàn toàn nguyên trạng, hãy đặt <code>convert_urls: False</code>.
Vì sao TinyMCE lưu ảnh được dán dưới dạng base64?
Theo mặc định, khi chưa cấu hình trình xử lý tải lên, TinyMCE sẽ nhúng ảnh được dán hoặc kéo thả trực tiếp dưới dạng URI dữ liệu base64. Trình soạn thảo vẫn hiển thị bình thường, nhưng HTML đã lưu lúc này chứa toàn bộ ảnh được mã hóa thành văn bản.
Làm cách nào để ngăn nhúng ảnh base64 trong django-tinymce?
Hãy cấu hình <code>images_upload_url</code> (hoặc <code>images_upload_handler</code>) để TinyMCE tải ảnh lên và thay base64 bằng URL được trả về. Nếu muốn từ chối hoàn toàn ảnh nội tuyến, hãy đặt <code>paste_data_images: False</code>.