【问题标题】:Summernote image uploadSummernote 图片上传
【发布时间】:2014-03-04 21:25:40
【问题描述】:

我对编辑器 Summernote 有疑问。我想将图像上传到服务器上的目录中。 我有一些脚本:

<script type="text/javascript">
  $(function () {
    $(\'.summernote\').summernote({
      height: 200
    });
    $(\'.summernote\').summernote({
     height:300,
     onImageUpload: function(files, editor, welEditable) {
      sendFile(files[0],editor,welEditable);
    }
  });

  });
</script>
<script type="text/javascript">
  function sendFile(file, editor, welEditable) {
    data = new FormData();
    data.append("file", file);
    url = "http://localhost/spichlerz/uploads";
    $.ajax({
      data: data,
      type: "POST",
      url: url,
      cache: false,
      contentType: false,
      processData: false,
      success: function (url) {
        editor.insertImage(welEditable, url);
      }
    });
  }
</script>



<td><textarea class="summernote" rows="10" cols="100" name="tekst"></textarea></td>

当然,我有所有的 js 和 CSS 文件。 我做错了什么?如果我点击图片上传并进入编辑器,图片不在 textarea 中。

如果我删除 sendFile 函数和 onImageUpload:图像保存在 base64 上。

summernote链接:http://hackerwins.github.io/summernote/

【问题讨论】:

    标签: javascript image upload summernote


    【解决方案1】:

    我测试了这段代码并且可以工作

    Javascript

    <script>
    $(document).ready(function() {
      $('#summernote').summernote({
        height: 200,
        onImageUpload: function(files, editor, welEditable) {
          sendFile(files[0], editor, welEditable);
        }
      });
    
      function sendFile(file, editor, welEditable) {
        data = new FormData();
        data.append("file", file);
        $.ajax({
          data: data,
          type: "POST",
          url: "Your URL POST (php)",
          cache: false,
          contentType: false,
          processData: false,
          success: function(url) {
            editor.insertImage(welEditable, url);
          }
        });
      }
    });
    </script>
    

    PHP

    if ($_FILES['file']['name']) {
      if (!$_FILES['file']['error']) {
        $name = md5(rand(100, 200));
        $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
        $filename = $name.
        '.'.$ext;
        $destination = '/assets/images/'.$filename; //change this directory
        $location = $_FILES["file"]["tmp_name"];
        move_uploaded_file($location, $destination);
        echo 'http://test.yourdomain.al/images/'.$filename; //change this URL
      } else {
        echo $message = 'Ooops!  Your upload triggered the following error:  '.$_FILES['file']['error'];
      }
    }
    

    更新:

    0.7.0 之后onImageUpload 应该在@tugberk 提到的callbacks 选项内

    $('#summernote').summernote({
        height: 200,
        callbacks: {
            onImageUpload: function(files, editor, welEditable) {
                sendFile(files[0], editor, welEditable);
            }
        }
    });
    

    【讨论】:

    • 运行良好,干得好 - 注意:确保 $destination 是绝对路径
    • 嘿...如果您删除图像怎么办?
    • url: "Your URL POST (php)" 应该是哪个网址?我尝试将php上传功能的url放在codeigniter中,但不起作用。
    • 这是投票最多的答案,但不适用于 v0.8.8,请参阅 summernote.org/deep-dive/#onimageupload。您可能想更新您的答案,因为我花了几个小时才弄清楚:s
    • 多上传情况会怎样?
    【解决方案2】:

    Summernote v0.8.1 图片上传

    对于大图

    $('#summernote').summernote({
        height: ($(window).height() - 300),
        callbacks: {
            onImageUpload: function(image) {
                uploadImage(image[0]);
            }
        }
    });
    
    function uploadImage(image) {
        var data = new FormData();
        data.append("image", image);
        $.ajax({
            url: 'Your url to deal with your image',
            cache: false,
            contentType: false,
            processData: false,
            data: data,
            type: "post",
            success: function(url) {
                var image = $('<img>').attr('src', 'http://' + url);
                $('#summernote').summernote("insertNode", image[0]);
            },
            error: function(data) {
                console.log(data);
            }
        });
    }
    

    【讨论】:

    • 如何直接从 URL 上传图片?文件下载到我的服务器后,我想替换插入的图像链接到我的服务器路径。
    【解决方案3】:

    使用进度条上传图片

    我想我会扩展 user3451783 的答案并提供一个 HTML5 进度条。我发现在不知道是否发生任何事情的情况下上传照片非常烦人。

    HTML

    <progress></progress>
    
    <div id="summernote"></div>
    

    JS

    // initialise editor
    
    $('#summernote').summernote({
            onImageUpload: function(files, editor, welEditable) {
                sendFile(files[0], editor, welEditable);
            }
    });
    
    // send the file
    
    function sendFile(file, editor, welEditable) {
            data = new FormData();
            data.append("file", file);
            $.ajax({
                data: data,
                type: 'POST',
                xhr: function() {
                    var myXhr = $.ajaxSettings.xhr();
                    if (myXhr.upload) myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
                    return myXhr;
                },
                url: root + '/assets/scripts/php/app/uploadEditorImages.php',
                cache: false,
                contentType: false,
                processData: false,
                success: function(url) {
                    editor.insertImage(welEditable, url);
                }
            });
    }
    
    // update progress bar
    
    function progressHandlingFunction(e){
        if(e.lengthComputable){
            $('progress').attr({value:e.loaded, max:e.total});
            // reset progress on complete
            if (e.loaded == e.total) {
                $('progress').attr('value','0.0');
            }
        }
    }
    

    【讨论】:

    • 进度条不能用最新版本,你能用新版本的summernote吗?
    • @star18bit:应该可以了——我加的进度条功能和Summernote没有关系,我只是在文件发送时监听XMLHttpRequest的进度。
    • 与最新的summernote完美配合。一个巧妙的解决方案。非常感谢。
    • 我认为这不适用于当前版本。 editorwelEditable 这两个变量始终为空。编辑:见github.com/vsymguysung/ember-cli-summernote/issues/31
    【解决方案4】:

    此代码适用于新版本 (v0.8.12) (2019-05-21)

    $('#summernote').summernote({
            callbacks: {
                onImageUpload: function(files) {
                    for(let i=0; i < files.length; i++) {
                        $.upload(files[i]);
                    }
                }
            },
            height: 500,
        });
    
        $.upload = function (file) {
            let out = new FormData();
            out.append('file', file, file.name);
    
            $.ajax({
                method: 'POST',
                url: 'upload.php',
                contentType: false,
                cache: false,
                processData: false,
                data: out,
                success: function (img) {
                    $('#summernote').summernote('insertImage', img);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.error(textStatus + " " + errorThrown);
                }
            });
        };
    

    PHP 代码(上传.php)

    if ($_FILES['file']['name']) {
     if (!$_FILES['file']['error']) {
        $name = md5(rand(100, 200));
        $ext = explode('.', $_FILES['file']['name']);
        $filename = $name . '.' . $ext[1];
        $destination = 'images/' . $filename; //change this directory
        $location = $_FILES["file"]["tmp_name"];
        move_uploaded_file($location, $destination);
        echo 'images/' . $filename;//change this URL
     }
     else
     {
      echo  $message = 'Ooops!  Your upload triggered the following error:  '.$_FILES['file']['error'];
     }
    }
    

    【讨论】:

    • 谢谢纳马尔!你有没有想过处理删除和从服务器目录中删除的代码?如果是这样,将不胜感激发帖。谢谢!
    【解决方案5】:

    Summernote 默认将你上传的图片转换为 base64 编码的字符串,你可以处理这个字符串,或者像其他朋友提到的那样,你可以使用onImageUpload 回调来上传图片。你可以看看这个gist,我对其进行了一些修改以适应laravel csrf tokenhere。但这对我不起作用,我没有时间找出原因!相反,我通过基于this blog postserver-side solution 解决了它。它获取summernote的输出,然后上传图片并更新最终的markdown HTML。

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Storage;
    
    Route::get('/your-route-to-editor', function () {
        return view('your-view');
    });
    
    Route::post('/your-route-to-processor', function (Request $request) {
    
           $this->validate($request, [
               'editordata' => 'required',
           ]);
    
           $data = $request->input('editordata');
    
           //loading the html data from the summernote editor and select the img tags from it
           $dom = new \DomDocument();
           $dom->loadHtml($data, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);    
           $images = $dom->getElementsByTagName('img');
           
           foreach($images as $k => $img){
               //for now src attribute contains image encrypted data in a nonsence string
               $data = $img->getAttribute('src');
               //getting the original file name that is in data-filename attribute of img
               $file_name = $img->getAttribute('data-filename');
               //extracting the original file name and extension
               $arr = explode('.', $file_name);
               $upload_base_directory = 'public/';
    
               $original_file_name='time()'.$k;
               $original_file_extension='png';
    
               if (sizeof($arr) ==  2) {
                    $original_file_name = $arr[0];
                    $original_file_extension = $arr[1];
               }
               else
               {
                    //the file name contains extra . in itself
                    $original_file_name = implode("_",array_slice($arr,0,sizeof($arr)-1));
                    $original_file_extension = $arr[sizeof($arr)-1];
               }
    
               list($type, $data) = explode(';', $data);
               list(, $data)      = explode(',', $data);
    
               $data = base64_decode($data);
    
               $path = $upload_base_directory.$original_file_name.'.'.$original_file_extension;
    
               //uploading the image to an actual file on the server and get the url to it to update the src attribute of images
               Storage::put($path, $data);
    
               $img->removeAttribute('src');       
               //you can remove the data-filename attribute here too if you want.
               $img->setAttribute('src', Storage::url($path));
               // data base stuff here :
               //saving the attachments path in an array
           }
    
           //updating the summernote WYSIWYG markdown output.
           $data = $dom->saveHTML();
    
           // data base stuff here :
           // save the post along with it attachments array
           return view('your-preview-page')->with(['data'=>$data]);
    
    });
    

    【讨论】:

    • 一句废话,我的意思是base64加密数据。