問題描述:服務器系統架構採用的是koa(並不是koa2),客戶端富文本編輯器採用的是百度的ueditor控件。如今須要ueditor支持將圖片直接上傳到七牛雲。php
前提:百度的ueditor須要在本地配置爲可用,圖片上傳相關的配置能夠參考官方文檔的描述。因爲服務器用的node.js,所以ueditor目錄下咱們只須要保留nodejs目錄,其它部分如php,asp.net等均可以刪掉。而後根據本身服務器的環境適當修改config.json文件中的配置。node
現有方案:現有npm和github上找到的庫有不少是基於koa2的,並不是koa,因此不適用於本場景。找到一個koa-ueditor的庫,但只是將圖片上傳到服務器硬盤,缺乏將圖片上傳到七牛雲,固然咱們能夠補充這部分代碼,畢竟七牛也提供了相應的接口從服務器硬盤將圖片進行上傳。另外還有一個庫oeditor,相對來講比較老了,嘗試了一下,並不能正常工做,在debug的過程當中發現沒法獲取到圖片文件的數據,緣由多是由於在koa的框架中須要配合使用co-busboy。git
解決方案:嘗試對koa-ueditor庫進行改造,使其支持將圖片上傳到七牛。github
咱們將上傳的方法封裝成一箇中間件,代碼以下:npm
"use strict"; var Q = require('q'); var path = require("path"); var os = require('os'); var snowflake = require('node-snowflake').Snowflake; var qn = require('qn'); var parse = require('co-busboy'); var Rst = require('huanche-models').rst; var img_type = '.jpg .png .gif .ico .bmp .jpeg'; var img_path = '/ueditor/upload'; var Config = {}; function* ueditor(next){ if (this.query.action === 'config') { this.set("Content-Type","json"); this.redirect("/ueditor/nodejs/config.json"); } else if(this.query.action === 'uploadimage' || this.query.action === 'uploadfile'){ if (!Config.qn) { throw (new Rst()).error('缺乏qiniu配置'); } var parts = parse(this); var part; // var stream; var tmp_name; var file_path; var filename; var deferred = Q.defer(); while (part = yield parts) { if (part.length) { // fields are returned as arrays var key = part[0]; var value = part[1]; // check the CSRF token //if (key === '_csrf') this.assertCSRF(value); } else { // files are returned as readable streams // let's just save them to disk if(this.query.action === 'uploadimage' && img_type.indexOf(path.extname(part.filename)) >= 0 ){ var tmpdir = path.join(os.tmpdir(), path.basename(part.filename)); filename = snowflake.nextId() + path.extname(tmpdir); file_path = path.join(img_path, filename); tmp_name = part.filename; qn.create(Config.qn).upload(part, { key: 'ueditor/images/' + filename }, function (err, results) { if (err) deferred.reject(err); deferred.resolve(results); }); } } } var rst = yield deferred.promise.then(function (result) { // console.log(result); return result; }); this.body = { 'url': rst.url, 'title': filename, 'original': tmp_name, 'state': 'SUCCESS' }; }else{ this.body = { 'state': 'FAIL' }; } yield next; } module.exports = function(config){ if(config){ Config = config; } return ueditor; };
而後定義圖片上傳的路由,並指定七牛相關的參數配置。json
const router = require('koa-router')(); const ueditor_qiniu = require('../../middleware/koa_ueditor_upload_qiniu'); router.all('/ueditor/ue', ueditor_qiniu({ qn: { accessKey: 'xxxxxxxxxxx', // 七牛的accessKey secretKey: 'xxxxxxxxxxx', // 七牛的secretKey bucket: 'imgpub', // bucket origin: 'https://xxx.xxxx.com' // origin url } })); module.exports = router;
注意路由定義中的url部分,這個須要和ueditor目錄下的ueditor.config.js文件中所配置的serverUrl參數的值保持一致,不然運行時ueditor將沒法正確訪問路由。同時咱們還須要正確指定七牛上傳圖片相關的參數,傳給中間件的函數。promise
採用這種方式不須要指定服務器上的圖片上傳路徑,全部上傳的圖片會直接上傳到七牛雲,而後返回七牛的圖片地址給ueditor控件。服務器