概述
小书匠从 7.4.0
版本开始,提供了自定义图床功能。通过该功能,用户可以将图片上传到自己想要的图床系统上,再也不用受限于系统提供的默认几个有限图床。同时,通过自定义图床,还可以实现强大的多图床功能,即把一张图片上传到多个图床系统上。
操作
点击 小书匠主按钮>绑定>自定义图床 , 进入自定义图床设置界面。
参数设置说明
由于自定义图床逻辑完全交给用户控制,因此系统只提供了一个参数设置,即代码逻辑。该值需要使用 javascript 语法完成图片上传的相关操作,并回调执行操作后的结果返回给小书匠系统。
注: 需要对 javascript 语法有一定的了解。
代码逻辑及相关变量说明
-
上传图片的代码需要使用 javascript 语言完成
-
系统通过 javascript 的
new Function
(Function 定义 )将自定义的上传逻辑封装在一个函数内,当用户触发上传图片的操作时,自动执行该函数 -
当该函数执行时,除了系统默认的全局变量,比如
window
,$
等用户可以直接使用外,还额外提供了filename
,fileData
,opts
,callback
四个变量filename
为上传文件的原始文件名,如果是从剪切板上传的图片,系统自己创建一个文件名, 格式为字符串fileData
为上传文件的二进制内容,格式为 javascript 的blob
对像opts
提供了一些额外参数和方法, 目前提供了一个当前文件的md5
值(opts.md5)和getPlugins
方法 ( opts.getPlugins)- callback 回调函数,当图片上传完成后,需要执行该回调函数,并提供相关的回调参数,比如生成的 url 地址
-
在执行完上传图片后,需要用户执行一个回调函数
callback
, 将代码操作权重新返回给小书匠,回调函数需包含以下参数error
如果上传图片失败,需要提供一个error
描述失败原因,如果上传成功,直接提供一个null
值即可newFilename
如果用户想重新生成新的文件名,需要在这里返回该生成的新文件名,如果想保持不变,只需设置为null
即可。url
上传完图片后,返回的url
地址
注:系统并没有对全局变量进行隔离, 因此用户可以直接拿到像 window
, $
等对像,但需要注意的是,因为没有隔离变量,用户就可以随意修改全局对像的值,如果用户错误的修改了一个全局变量的值,会有系统崩溃的风险
调试逻辑代码
可以通过 web 版本的小书匠,在 chrome 浏览器上将自定义的代码调试通过后,再将该代码逻辑应用到客户端上
需要注意的是, web 版本存在跨域访问的限制,而客户端版本没有对该限制的要求。同时客户端版本还提供了对本地 nodejs 的 api 支持。
示例
添加一个自定义 imageURL 图床
使用的自定义图床服务为 https://www.xiaoz.me/doc/#/imgurl2/api , 用户可根据自己的实际需求选择自定义图床服务。
相关代码逻辑如下,注意 filename
, fileData
, opts
, callback
的变量要求
- 1const fd = new FormData();
- 2fd.append('file', new File([fileData], filename));
- 3$.ajax({
- 4 type: 'POST',
- 5 url: 'http://test.imgurl.org/api/upload',
- 6 data: fd,
- 7 processData: false,
- 8 contentType: false
- 9}).done(function(data){
- 10 try{
- 11 data = JSON.parse(data);
- 12 } catch(e){}
- 13 if (data.code != 200) {
- 14 callback('上传失败' + data.msg);
- 15 } else {
- 16 callback(null, filename, data.url, data);
- 17 }
- 18}).fail(function(res, status, message){
- 19 callback('上传资源失败:' + message);
- 20});
实现多图床功能
通过 opts.getPlugins
方法,获取到所有已经绑定的非自定义图床列表 plugins
,遍历该图床列表,取得自己想要额外保存的第三方图床,比如 const otherPlugin = plugins[0]
, 执行保存图片方法 otnerPlugin.saveFile(filename, fileData, function(error, newFilename, fileData){});
下面的例子演示了使用自定义的图床将图片上传到 imgurl 图床 , 并同时 将该图片上传到所有先前绑定的 smms 图床上。上传完成后,最终返回 imgurl
生成的地址做为文章内的显示地址。
注:为了防止多图床嵌套,系统只允许用户拿到所有非自定义图床绑定的相关信息。也就是只列出小书匠内置支持的图床列表,比如 github, gitee, smms等图床。
- 1const fd = new FormData();
- 2fd.append('file', new File([fileData], filename));
- 3plugins = opts.getPlugins(function(pluginObj){
- 4
- 5 // 可以通过 console.log(pluginObj) 在调试器里打印出所有支持的图床
- 6 console.log(pluginObj)
- 7
- 8 // pluginObj.id 里的 id 值对应绑定列表里显示的 id 值,
- 9 // 这里可以根据自己的业务逻辑需求,过滤 id, displayName 或者 name
- 10 // id 为用户每次绑定一个新的第三方图床时,系统自动生成的一个值,可以在绑定列表里查看到
- 11 // displayName 是用户指定生成的一个名称,就是在绑定列表里,用户可以修改显示的名称
- 12 // name 系统预设的一个名称,比如 github 图床为 githubimg, gitee图床为 giteeimg 等
- 13
- 14 return pluginObj.name === 'smms';
- 15})
- 16function pluginUpload(plugin, cb){
- 17 plugin.saveFile(filename, fileData, function(err, _filename, _url, info){
- 18 if (err) {
- 19 console.error('使用图床 ' + plugin.displayName + ' 上传图片失败: ' + err);
- 20 }
- 21 cb();
- 22 });
- 23}
- 24function allPluginUploaded(){
- 25 console.log('所有资源已经上传到相关图床上了');
- 26}
- 27async.mapLimit(plugins, 10, pluginUpload, allPluginUploaded);
- 28
- 29$.ajax({
- 30 type: 'POST',
- 31 url: 'http://test.imgurl.org/api/upload',
- 32 data: fd,
- 33 processData: false,
- 34 contentType: false
- 35}).done(function(data){
- 36 try{
- 37 data = JSON.parse(data);
- 38 } catch(e){}
- 39 if (data.code != 200) {
- 40 callback('上传失败' + data.msg);
- 41 } else {
- 42 callback(null, filename, data.url, data);
- 43 }
- 44}).fail(function(res, status, message){
- 45 callback('上传资源失败:' + message);
- 46});
常见问题
如何带认证上传图片
可以通过自定义 headers , url params 或者添加额外 body form 的上传信息,来达到上传图片时,带上认证信息。
比如前面的两个例子里,使用了 jQuery 的 ajax 函数, 想要带上 headers, 可以参考下面的代码
- 1$.ajax({
- 2 type: 'POST',
- 3 url: 'http://test.imgurl.org/api/upload',
- 4 data: fd,
- 5 processData: false,
- 6 contentType: false,
- 7 headers: {
- 8 "My-First-Header":"first value",
- 9 "My-Second-Header":"second value"
- 10 }
- 11})
详细使用,可以参考该函数的说明
用户也可以使用 HTML5 提供的 fetch 函数,实现 ajax 请求。