Vanhiep.NET - Chuyên gia Thiết kế Website & Ứng dụng

Hiển thị thẻ Iframe trong CKEditor: Hướng dẫn chi tiết cấu hình

Đoạn hướng dẫn này cung cấp các bước chi tiết để cấu hình CKEditor, giúp trình soạn thảo hiển thị trực tiếp thẻ <iframe> trong nội dung. Bạn sẽ tìm hiểu cách chỉnh sửa file JavaScript cài đặt CKEditor để cho phép <iframe> thông qua các tùy chọn allowedContent hoặc extraAllowedContent và đảm bảo hiển thị đúng cách.

Để hiển thị thẻ <iframe> trong trình soạn thảo CKEditor, bạn cần cấu hình lại một số tùy chọn để CKEditor không loại bỏ hoặc lọc bỏ thẻ này. Dưới đây là cách bạn có thể sửa đổi đoạn mã JavaScript của mình:

<script type="text/javascript">
    $(document).ready(function() {
        url = base_url() + 'assets/ckfinder/';

        // Cấu hình chung cho phép iframe
        // LƯU Ý QUAN TRỌNG: allowedContent: true sẽ cho phép tất cả các thẻ và thuộc tính.
        // Hãy cẩn thận khi sử dụng nếu bạn không kiểm soát nội dung đầu vào.
        // Đây là cách đơn giản nhất để hiển thị iframe.
        var commonCKEditorConfig = {
            allowedContent: true, // Cho phép tất cả nội dung (bao gồm iframe)
            on: {
                instanceReady: function( evt ) {
                    var editor = evt.editor;
                    // Đảm bảo iframe không bị loại bỏ khi hiển thị trong trình soạn thảo
                    editor.dataProcessor.htmlFilter.addRules( {
                        elements: {
                            iframe: function( element ) {
                                return element;
                            }
                        }
                    });
                }
            }
        };

        // CKEditor 'ckeditor_description'
        // Thêm cấu hình iframe vào instance này
        CKEDITOR.replace('ckeditor_description', commonCKEditorConfig);

        // CKEditor 'ckeditor_content'
        // Kết hợp cấu hình hiện có của bạn với cấu hình cho phép iframe
        CKEDITOR.replace('ckeditor_content', $.extend(true, {}, commonCKEditorConfig, {
            height: 200,
            title: '',
            extraPlugins: 'codesnippet',
            codeSnippet_theme: 'school_book',
            codeSnippet_languages: {
                javascript: 'JavaScript',
                php: 'PHP',
                apache: 'Apache',
                bash: 'Bash',
                coffeescript: 'CoffeeScript',
                cpp: 'C++',
                cs: 'C#',
                css: 'CSS',
                diff: 'Diff',
                html: 'HTML',
                http: 'HTTP',
                ini: 'INI',
                java: 'Java',
                json: 'JSON',
                makefile: 'Makefile',
                markdown: 'Markdown',
                nginx: 'Nginx',
                objectivec: 'Objective-C',
                perl: 'Perl',
                python: 'Python',
                ruby: 'Ruby',
                sql: 'SQL',
                vbscript: 'VBScript',
                xhtml: 'XHTML',
                xml: 'XML'
            },
            filebrowserBrowseUrl: url + 'ckfinder.html',
            filebrowserImageBrowseUrl: url + 'ckfinder.html?type=Images',
            filebrowserUploadUrl: url + 'core/connector/php/connector.php?command=QuickUpload&type=Files',
            filebrowserImageUploadUrl: url + 'core/connector/php/connector.php?command=QuickUpload&type=Images',
            filebrowserUploadMethod: 'form',
        }));
    });
</script>

Giải thích các thay đổi:

  1. commonCKEditorConfig Object: Tôi đã tạo một đối tượng cấu hình chung (commonCKEditorConfig) để chứa các cài đặt cho phép <iframe>. Điều này giúp bạn dễ dàng áp dụng cùng một cấu hình cho nhiều instance CKEditor.

    • allowedContent: true: Đây là cài đặt quan trọng nhất. Nó vô hiệu hóa Bộ lọc nội dung nâng cao (ACF) của CKEditor, cho phép tất cả các thẻ HTML (bao gồm <iframe>), thuộc tính và kiểu CSS được giữ nguyên trong trình soạn thảo.

      • Cảnh báo bảo mật: Việc đặt allowedContent: true có thể khiến trang web của bạn dễ bị tấn công XSS (Cross-Site Scripting) nếu bạn cho phép người dùng không đáng tin cậy dán nội dung. Nếu đây là một rủi ro, bạn nên xem xét các tùy chọn an toàn hơn như extraAllowedContent (xem phần "Tùy chọn thay thế an toàn hơn" bên dưới).
    • on: { instanceReady: function( evt ) { ... } }: Phần này đảm bảo rằng khi trình soạn thảo đã sẵn sàng, một quy tắc htmlFilter được thêm vào. Quy tắc này ngăn CKEditor ẩn hoặc loại bỏ thẻ <iframe> khi hiển thị trong khu vực chỉnh sửa, giúp bạn thấy được <iframe> trực tiếp.

  2. Áp dụng cấu hình:

    • Đối với CKEDITOR.replace('ckeditor_description'): Tôi chỉ cần truyền commonCKEditorConfig vào đây.
    • Đối với CKEDITOR.replace('ckeditor_content'): Tôi sử dụng $.extend(true, {}, commonCKEditorConfig, { ... }); để kết hợp cấu hình commonCKEditorConfig với tất cả các cấu hình hiện có của bạn (như height, extraPlugins, codeSnippet_languages, filebrowser...). Điều này đảm bảo rằng tất cả các cài đặt tùy chỉnh khác của bạn vẫn hoạt động.

Các bước tiếp theo:

  1. Cập nhật mã: Sao chép và dán đoạn mã JavaScript đã sửa đổi vào tệp của bạn.
  2. Xóa bộ nhớ cache: Sau khi cập nhật, hãy đảm bảo bạn xóa bộ nhớ cache của trình duyệt (Ctrl+Shift+R hoặc Cmd+Shift+R) để các thay đổi có hiệu lực.
  3. Kiểm tra: Mở trình soạn thảo CKEditor và thử nhúng một thẻ <iframe> (ví dụ: một video YouTube hoặc Google Maps) để xem nó có hiển thị trực tiếp trong trình soạn thảo hay không.

Tùy chọn thay thế an toàn hơn (nếu bạn không muốn dùng allowedContent: true):

Nếu bạn lo ngại về bảo mật khi sử dụng allowedContent: true, bạn có thể sử dụng extraAllowedContent để chỉ cho phép <iframe> và các thuộc tính cụ thể của nó. Đây là cách an toàn hơn nhưng đòi hỏi bạn phải liệt kê rõ ràng các thuộc tính:

// Thay thế commonCKEditorConfig bằng cấu hình này
var commonCKEditorConfig = {
    // Không dùng allowedContent: true
    extraAllowedContent: 'iframe[src,width,height,frameborder,allowfullscreen,title,referrerpolicy,loading]{*}', // Cho phép iframe với các thuộc tính phổ biến
    on: {
        instanceReady: function( evt ) {
            var editor = evt.editor;
            editor.dataProcessor.htmlFilter.addRules( {
                elements: {
                    iframe: function( element ) {
                        return element;
                    }
                }
            });
        }
    }
};
// Sau đó áp dụng commonCKEditorConfig tương tự như trên.

Với extraAllowedContent: 'iframe[src,width,height,frameborder,allowfullscreen,title,referrerpolicy,loading]{*}', bạn chỉ cho phép thẻ <iframe> cùng với các thuộc tính đã liệt kê. Nếu <iframe> của bạn có các thuộc tính khác không được liệt kê, chúng sẽ bị loại bỏ. Dấu {*} cho phép bất kỳ kiểu CSS nội tuyến nào trên thẻ <iframe>.