有没有想过用WordPress来建立自己的文件存储空间,当作自己的网盘使用?这个业务实现的主要逻辑其实就是自己写一个Rest API接口上传文件到WP的媒体库中。
首先我们需要安装一个插件,这个插件很小,只是给网站后台登录提供Basic认证,并不是用来拓展业务接口的。开通了Basic认证方式,我们才有途径获得使用Rest API更新网站内容的权限,否则Rest API只提供读取权限。插件名称叫做JSON Basic Authentication,官方下载地址:https://github.com/WP-API/Basic-Auth
要做接口,就先创建endpoint。这次我创建两个,一个是用来转存网上的文件的,一个是用来自己上传文件的。
add_action( 'rest_api_init', function () { //如果你不打算把文件存到WP默认的位置,这是修改位置的钩子 add_filter( 'upload_dir', 'brain1981_upload_dir'); //转存 register_rest_route( 'brain1981/v1', '/catch/', array( 'methods' => 'POST', 'callback' => 'brain1981_api_post_catch', ) ); //上传 register_rest_route( 'brain1981/v1', '/stream/', array( 'methods' => 'POST', 'callback' => 'brain1981_api_post_stream', ) ); }); |
如果你不打算把文件存到WP默认的位置,这是修改位置的函数
function brain1981_upload_dir( $param ){ // 指定子目录名称 $mydir = '/my-path'; // 在默认位置(WP后台设定的年份和月份文件夹)下新建my-path子目录存储文件 $param['path'] = $param['path'] . $mydir; $param['url'] = $param['url'] . $mydir; return $param; // 存到uploads下的my-path子目录 // $param['path'] = $param['basedir'] . $mydir; // $param['url'] = $param['baseurl'] . $mydir; // return $param; } |
接下来是处理函数
转存文件
function brain1981_api_post_catch($request){ $file_url = $request['url']; //如有需要,可以给所有通过这个接口存储的文件名加一个前缀 $file_prefix = 'prefix_'; $file_content=file_get_contents($file_url); $url_api = site_url("/wp-json/wp/v2/media/"); $file_name = $request['filename']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_api ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($ch, CURLOPT_POST, 1 ); curl_setopt($ch, CURLOPT_POSTFIELDS, $file_content); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'content-disposition: attachment; filename='.$file_prefix.$file_name.'"', 'authorization: ' . $_SERVER['HTTP_AUTHORIZATION'] ) ); $result=curl_exec($ch); if(json_decode($result)->id){ return json_decode($result)->guid->rendered ; }else{ return json_decode($result)->data->status . " " .json_decode($result)->message; } } |
上传文件
function brain1981_api_post_stream($request){ $file_content = $request['content']; $file_content = base64_decode($file_content); $file_name = $request['filename']; //如有需要,可以给所有通过这个接口存储的文件名加一个前缀 $file_prefix = 'prefix_'; $url_api = site_url("/wp-json/wp/v2/media/"); if(!empty($request['mime'])){ $mime = $request['mime']; }else{ $mime="text/plain"; } $file_name = $request['filename']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_api ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($ch, CURLOPT_POST, 1 ); curl_setopt($ch, CURLOPT_POSTFIELDS, $file_content); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'content-disposition: attachment; filename='.$file_prefix.$file_name, 'cache-control: no-cache', 'authorization: ' . $_SERVER['HTTP_AUTHORIZATION'], 'content-type: ' . $mime ) ); $result=curl_exec($ch); if(json_decode($result)->id){ return json_decode($result)->guid->rendered ; }else{ return json_decode($result)->data->status . " " .json_decode($result)->message." "; } } |
这样接口就建立完毕了,下面是如何请求这两个接口。
转存文件,接口URL: http(s)://网站域名/wp-json/brain1981/v1/catch/
请求格式为JSON:
{ "url": "附件的url地址,需包含http://或https://", "filename": "文件名" } |
直接上传文件,接口URL: http(s)://网站域名/wp-json/brain1981/v1/stream/
请求格式:
{ "content": "数据流内容..数据流内容", "filename": "文件名", "mime": "文件格式" } |
请求格式的注意点:
– 请注意JSON最后一行不能有逗号
– 视服务器条件而定,服务器会有一定的响应时间限制,原则上应该无法接受超过50M的数据(LNMP默认环境),过大的数据流会造成超时和发送失败
– filename文件名请包含合法的扩展名,暂只支持jpg,gif、png、pdf等常见格式
– mime文件格式:填写对应文件的格式,如“image/jpeg”、“image/png”、“image/gif”、“application/pdf”、“application/pdf”或“text/plain”
– content数据流的内容,可以直接把文件通过二进制数据写到这个JSON中
接下来我们需要通过Basic认证获取API的权限,再使用上面写出来的接口上传文件。
获取权限,就要在请求的头部把登录信息转换成Base64字符串,具体格式是这样的:
Authorization: Basic {base64_encode([username]:[password])}
Content-Type: application/json
提供一个JS的范例,用来转存文件:
$.ajax({ url: 'http(s)://网站域名/wp-json/brain1981/v1/catch/', method: 'POST', crossDomain: true, data: { "url": "http://xxx.xxx/abc.jpg", "filename": "xyz.jpg" }, beforeSend: function ( xhr ) { //以下这行要改成自己真实的用WP户名和密码,并且账号需具有editor或以上权限 xhr.setRequestHeader( 'Authorization', 'Basic ' + Base64.encode( 'username:password' ) ); }, success: function( data, txtStatus, xhr ) { console.log( data ); console.log( xhr.status ); } }); //认证字符串的Base64编码库 var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}; |
2022年2月7日更新:增加了修改存放目录的代码
–全文完–
本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.brain1981.com/2194.html。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。