當使用者在後台管理商品資料的時候,必須用到編輯器讓使用者輸入資料,當然也少不了常常跟編輯期搭配使用的圖片上傳,這邊選用Shrine跟Summernote來當作例子,講解前端如何發起上傳圖片的request將圖片上傳到後端。
解釋一下:Shrine 是Rails 裡面一套圖片上傳的套件,而Summernote 是一套歷久彌新而且非常好用的所見即所得編輯器,你應該會常常在各大開源專案看到他的影子。
今天重點會著重在前端圖片上傳到後端,並回傳圖片位址的流程,在後端功能的實作上不會有有太詳細的解說。
Summernote 文件:https://summernote.org/
Shrine 文件:https://github.com/shrinerb/shrine
OUTLINE
- HTML編輯器功能說明
- 圖片上傳流程解析
- 實際程式碼
HTML編輯器功能說明:
HTML編輯器的介面其實長得很像Word,有各種按鈕讓你設定跟編輯文字的外觀。只不過你在Web使用編輯器的時候,實際上是在編輯他的Css Style,去改變文字大小、顏色等外觀。
Summernote 使用上非常容易,搭配jquery的selector就可以很快成功有一個編輯器介面可以用:
<div id="summernote"></div>
$('#summernote').summernote();
圖片上傳流程解析:
要能夠在編輯器裡面上傳並插入圖片,大致上有兩個關鍵步驟:
- 使用者選擇要上傳的圖片
- 上傳完畢,拿回圖片網址,並將圖片插入目前游標位置
我們可以看到在上述編輯器裡面有個圖片上傳按鈕,以Web以及Javascript的角度來思考的話,點擊該按鈕應該會有一個callback,就算沒有我們也可以自己實作一個,不過既然Summernote預設就有這個按鈕,我猜想應該會有一個點擊上傳圖片後的hook,可以自己寫callback來決定使用者選擇圖片後,要做什麼動作。
果不其然在官方文件被我找到這個 onImageUpload 的hook:
在callback參數裡面可以拿到使用者選擇的檔案,只要在這個callback裡面利用ajax進行圖檔上傳的動作,就可以順利上傳了,甚至在文件裡還有提供插入圖片到游標位置的方法:
// upload image to server and create imgNode...
$summernote.summernote('insertNode', imgNode);
既然有了方法,就可以整理一下圖片上傳的流程:
實際程式碼:
jquery ajax圖片上傳:
function imageUpload(files){
let formData = new FormData();
formData.append('upload', files[0]);
return $.ajax({
type: "POST",
url: '/upload',
data:formData,
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]')
.attr('content'))},
cache : false,
contentType : false,
processData : false,
});
}
我把ajax內容拆了出來,把資料用參數的方式傳遞,以免每次上傳都要重寫一次:
callback 內容
$('#summernote').summernote(
{ height: 300,
callbacks: {
onImageUpload: function(files) {
imageUpload(files).done((data, textStatus, jqXHR)=>{
let url = "/uploads/"+data.imageUrl
$('#summernote').summernote('insertImage', url, 'newimage');
})
},
}
});