简介与入门 \ 上传图片和文件

此页更新时间:2020-10-28 14:56

此页英文文档:https://www.tiny.cloud/docs/general-configuration-guide/upload-images/

译者:此节原文说的比较乱,我彻底重写了一下,已经变成另一篇文章了。如看原文请点上面链接。

实现图片上传

要使TinyMCE能够上传图片,需要如下几步:

第1步:上传图片,首先要启用图片插件

在plugins参数中把image加进去。

第2步:在工具栏显示图片工具按钮

在toolbar参数中把image加进去。

此时,点图片按钮是没有上传选项的,只能添加图片地址。

第3步:加入配置参数images_upload_url

此参数用于指定一个接受上传文件的后端处理程序地址,例如:

images_upload_url: '/demo/upimg.php',

如果返回的地址是相对路径,还有一个参数images_upload_base_path,可以给相对路径指定它所相对的基本路径。

images_upload_base_path: '/demo',

最后如下方示例:

tinymce.init({
    selector: '#tinydemo',
    language:'zh_CN',
    plugins: 'image',
    toolbar: 'image',
    images_upload_url: '/demo/upimg.php',
    images_upload_base_path: '/demo',
});

对于后端程序对上传图片的处理不在本文范围内。这里只做几点说明。

后端返回给TinyMCE的JSON数据,形如这样:{ location : "/demo/image/1.jpg" }

跨域问题:源文档重点对此进行了说明,如果TinyMCE和接受上传图片程序未在同一域名下,浏览器会因跨域问题而拒绝操作,后端程序返回结果时,需给浏览器一个允许跨域的指令,对于PHP,写法如下:

header('Access-Control-Allow-Origin: *');

这里的*代表允许所有,你可以换成你自己的域名(只能写一个)

一般是使用一个白名单数组,然后通过类似PHP里的$_SERVER['HTTP_ORIGIN']判断是否跨域,以及请求是否在白名单内。

文档提供了一个php图片上传示例作为参考,代码很精简。

有关图片上传的参数

选项名称 说明
images_upload_url 指定上传图片的后端处理程序的URL。
images_upload_base_path 给返回的相对路径指定它所相对的基本路径。
images_upload_credentials 对images_upload_url中指定的地址调用时是否传递cookie等跨域的凭据。值为布尔值,默认false。
images_upload_handler 此选项允许你使用自定义函数代替TinyMCE来处理上传操作。该自定义函数需提供三个参数:blobInfo、成功回调和失败回调。

自定义前端上传逻辑

使用 images_upload_handler 可自定义上传处理逻辑。使用该配置,则无需使用其他上传配置选项。

最新版tiny为images_upload_handler加入了第四个参数:上传进度,可参考:配置参考 \ 图片&文件上传配置,本例兼容旧版,未使用第四个参数。

例:

tinymce.init({
    selector: '#tinydemo',
    plugins: 'image',
    toolbar: 'image',
    images_upload_handler: function (blobInfo, succFun, failFun) {
        var xhr, formData;
        var file = blobInfo.blob();//转化为易于理解的file对象
        xhr = new XMLHttpRequest();
        xhr.withCredentials = false;
        xhr.open('POST', '/demo/upimg.php');
        xhr.onload = function() {
            var json;
            if (xhr.status != 200) {
                failFun('HTTP Error: ' + xhr.status);
                return;
            }
            json = JSON.parse(xhr.responseText);
            if (!json || typeof json.location != 'string') {
                failFun('Invalid JSON: ' + xhr.responseText);
                return;
            }
            succFun(json.location);
        };
        formData = new FormData();
        formData.append('file', file, file.name );//此处与源文档不一样
        xhr.send(formData);
    }
});

实现文件上传

原文里只涉及了图片上传,文件上传没有说明,译文这里进行了补充。

很遗憾,文件上传没省事儿的办法,只能使用 file_picker_callback 写回调。

不过也别担心,我这里会给出例子,如果你能搞定图片上传,这里照抄就好了。

让我们继续一步一步来。

第1步:先启动个支持上传文件的插件

在plugins参数中把link加进去。

第2步:在工具栏显示链接编辑按钮

在toolbar参数中把link加进去。

此时,点链接工具是没有任何地方能上传文件的。

第3步:添加file_picker_callback参数

file_picker_callback: function(callback, value, meta) {}

这里我们先扔一个空函数,什么都不干,然后再次点编辑链接,这时在地址输入框的右侧,会显示一个上传的小图标。

最后如下方示例:

tinymce.init({
    selector: '#tinydemo2',
    language:'zh_CN',
    plugins: 'link',
    toolbar: 'link',
    file_picker_callback: function(callback, value, meta) {},
});

因为是个空函数,所以你点图标是没有任何反应的。

为了由浅入深,我们先来个从官方那找来的代码示例。

tinymce.init({
    selector: '#tinydemo3',
    language:'zh_CN',
    plugins: 'link',
    toolbar: 'link',
    file_picker_callback: function(callback, value, meta) {
        // Provide file and text for the link dialog
        if (meta.filetype == 'file') {
            callback('mypage.html', {text: 'My text'});
        }
        // Provide image and alt text for the image dialog
        if (meta.filetype == 'image') {
            callback('myimage.jpg', {alt: 'My alt text'});
        }
        // Provide alternative source and posted for the media dialog
        if (meta.filetype == 'media') {
            callback('movie.mp4', {source2: 'alt.ogg', poster: 'image.jpg'});
        }
    },
});

我觉得吧,官方是想通过这个例子,来说明TinyMCE贴心地帮你把文件给你分了类型,让你可以根据不同的类型分别处理上传。

既然提到文件类型,就顺便把这个参数说了吧。

file_picker_types:此选项可以通过空格或逗号分隔的类型名称指定允许上传的类型。目前只有三个可用的值:file、image和media。全填上就这么写:

file_picker_types: 'file image media'

三个参数分别对应三个插件【link,image,media】,如果要屏蔽某个插件的上传,就去掉对应参数。

下面是根据图片上传改写的文件上传。

tinymce.init({
    selector: '#tinydemo4',
    language:'zh_CN',
    plugins: 'link',
    toolbar: 'link',
    file_picker_callback: function (callback, value, meta) {
        //文件分类
        var filetype='.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4';
        //后端接收上传文件的地址
        var upurl='/demo/upfile.php';
        //为不同插件指定文件类型及后端地址
        switch(meta.filetype){
            case 'image':
                filetype='.jpg, .jpeg, .png, .gif';
                upurl='upimg.php';
                break;
            case 'media':
                filetype='.mp3, .mp4';
                upurl='upfile.php';
                break;
            case 'file':
            default:
        }
        //模拟出一个input用于添加本地文件
        var input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.setAttribute('accept', filetype);
        input.click();
        input.onchange = function() {
            var file = this.files[0];

            var xhr, formData;
            console.log(file.name);
            xhr = new XMLHttpRequest();
            xhr.withCredentials = false;
            xhr.open('POST', upurl);
            xhr.onload = function() {
                var json;
                if (xhr.status != 200) {
                    failure('HTTP Error: ' + xhr.status);
                    return;
                }
                json = JSON.parse(xhr.responseText);
                if (!json || typeof json.location != 'string') {
                    failure('Invalid JSON: ' + xhr.responseText);
                    return;
                }
                callback(json.location);
            };
            formData = new FormData();
            formData.append('file', file, file.name );
            xhr.send(formData);

            //下方被注释掉的是官方的一个例子
            //放到下面给大家参考
            
            /*var reader = new FileReader();
            reader.onload = function () {
                // Note: Now we need to register the blob in TinyMCEs image blob
                // registry. In the next release this part hopefully won't be
                // necessary, as we are looking to handle it internally.
                var id = 'blobid' + (new Date()).getTime();
                var blobCache =  tinymce.activeEditor.editorUpload.blobCache;
                var base64 = reader.result.split(',')[1];
                var blobInfo = blobCache.create(id, file, base64);
                blobCache.add(blobInfo);

                // call the callback and populate the Title field with the file name
                callback(blobInfo.blobUri(), { title: file.name });
            };
            reader.readAsDataURL(file);*/
        };
    },
});

demo就不放了,免得被人传些乱七八糟的东西:(

注:文件上传设置包含图片上传,配置文件上传后图片插件也会显示上传按钮,但tab栏不会出现上传选项。

下一节是内容过滤

下一节本来是“拼写检查”,但译者觉得这东西对国人意义不大,所以跳过了,如感兴趣可以看“拼写检查[英文]