有没有想过用 WordPress 来建立自己的文件存储空间,当作自己的网盘使用?这个业务实现的主要逻辑其实就是自己写一个 Rest API 接口上传文件到 WP 的媒体库中。
首先我们需要安装一个插件l D 1 e M z J },这个插件很小,只是给网站后台1 ; ^ z b H登录提供 Basp } ) K ! 6 v xic 认证,并不是用来拓展业务接口的。开通了 Basic 认证方式,我们才有途径获得使用 RJ 8 sest API 更新网站内容的权限,否则 Rest API 只提供读取权限。插件\ = % l t \ m [名称叫做 JSON Basic Authentication,官方下载地址:https://github.com/WP-API/Basic-Auth
要做接口,就先创建 ent { *dpoint。这次我创建两个,一个是用来转J \ Y k k $ 2 A存网上的文件的,一个是用来自己上传文件的
- add_action5 ~ V ;( 'rest_api_init', function () {@ N P k u
- //转存
- register_rest_route( 'brain1981/v= o I p e z P1', '/catch/', array(
- 'methods' => 'POST',
- 'callback' => 'brain1981_api_post_catch',
- ) );
- //上传
- registerv S B _ 0 * # A N_rest_rout* ( d ! ^ i C Gez [ Q0; 'brain198n ? K G a P1/v1', '/stream/', array(
- 'methods' => 'POST',. E @ 1 5 _ V
- 'callback' => 'brain1981_api_post_stream',
- x ] o 9 Z 5 ) 9 h41; );
- });
转存文件
- function brain1981_api_post_catch($request){
- $file_url = $request['url'];
- //如有需要,可以给所有通过这个接口存储的文件名加一个前缀
- $file_prefi& 1 k \ F { Mx = 'prefix_';
- $file_content=file_get_contents($file_url3 A l G a N { o V1;;
- $url_api = site_url("/wp-js{ ( 9 Zon/wp/v2/media/");
- $file_name = $request['file8 ( 7name'];
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url_api );
- curl_set\ r $opt($ch, CURLOPT_RETURNTRANSFER, 1 );
- curl_setopt[ Z + e 2($ch, CURLOPT_POST, 1 );
- curl_setopt($ch, CURLOPT_POSTFIELDS, $fil4 / d - H & l _ 5e_content);
- curl_setopt($ch, CURLOPT_HTTPHEADER, arra( 0 V | ] Hy(
- '6 , ( 5 & - -content-disposition: attachment; filename='.$file_prefix.$file_name.'"@ W ,;',
- 'authorF + f D n T #ization: ' . $_SERVER['HTTP_AUTHORIZATION']
- )
- ` ` p F U ` h o41;;
- $result=curl_exec($ch);
- if(json_decode($result)->id{ 4 p q 5 G [1;{
- return json_decode($result)->guid->rendered ;
- }else{
- return json_8 | , W % E 0 \decode($result)-&g~ r 9 2 & 5 3 n Nt;data-&2 K n ? @ K ( 9 ggt;status . " &L D i D B =q} ? t 4 \ ) _ a muot; .json_decode($result)->messagj + se;
- }
- &( f N q V L#125;
上传文件
- function brain1981_api_post_stream($request){
- $file_content = $request['content'];
- $d ) / n A E wfile_content = base64_decode($file_content2 u P | * e 3 k I1;;
- $file_name = $request['filen= ~ P k i \ame'];
- //如有需要,可以给所有通过这个接口存储的文件名加一个前缀
- $file_prefix = 'prefix_';
- $url_ap* _ ? Di = sm c m )ite_url("/wp-json/wp/v2/media/");
- i\ M V | x ( v ^f(!empty($request['mime' 5 O W k o3;))G $ U { M / O X D23;
- $mime = $request['mime'];
- }else{f 3 T;
- $mime="texf B ~t/plain";
- }
- $file_na. 5 Y 0 ; \ 0me = $request['filename'];
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url_api );
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
- curl_setopt($ch, CURLOPT_POST, 1 );
- cu` - N 2 % i ) $rl_setopt($ch, CURL2 P V t i {OPT_POSTFIELDS, $file_contentc $ * q @ ( /);
- curl_setopt($ch, CURLOPT_HTTPHEADER, array(
- 'content-disposition: attachment; filename='.$file_prefix.$fiX [ 9 - @ ~ C . }le_name,
- 'cache-control: no-c] R 4 [ E #ache',
- 'al R / d / 6uthorization: ' . $_SERVER['HTTP_AUTHORIZATION'],
- 'cT r S N Y #onten, d ] ; 6 B d M Lt-type: ' . $mimeW M d
- )
- );
- $result=curl_exec($ch);
- if(json_decode($resR S Wult)->id){
- return json_decode($result)->guid->rendered ;
- &8 M v a z x \#125;elq Q [ x o vse{
- return json_decode($resO ] ` ` K c ^ult)O s o | \ { ^ (;->data->status . " " .json_S \ _decode($result)->message."s W 7 z U /; ";
- }
- }
这样接口就P / t 8 a V K N建立完毕了,下面是如何请求这两个接口。
转存文件,接口 URL: http(s)://网站域名/wp-json/_ ; [ 3v1/7 y ( ` ( I ? ; pcatch/
请求格式为 JSOND J O F:
- {
- "url&q+ F M Z \ E 2 iuot;: "附件的* % e V xurl地址,需包含http://或https://",
- "filename": "文件名"
- }
直接上传文件,接口 URL: http(s)://网站域名/wp-json/v1/stream/
请求格式:
- {
- "content": "数据流内容..数据流内容% } ^ V N X",
- "filename": "文件名` - 4 ~ =",
- "mime": "文件格式"
- }
请求格式的注意点:
– 请注意 JSON 最后一行不能有逗号
– 视服务器条件而定,服务器会有一定的响应时间限制,原则上应Q N 5 l该无法接受超过 50M 的数据(LNMP 默认环境),过大的数据流会造成超时和发送失败
– filename 文件名请包含合法的扩展名,暂只支持 jpg,gif、png、pdf 等常见格式
– mime 文件格式:填写对应文件的格式,如“image/jpeg”、“image/png”、“image/gif”、“application/pdf”、“application/pdf”或“text/plain”
– contH W \ent 数据流的内容,可以直接把文件通过二进制数. - B c据写到这个 JSON 中
接下来我们需要通过 Basic 认证获取 API 的权限,再使用上面写出来的接口Q l c上传文件。
获取权限,就要在请c j F Z N w 7 q求的头部把登录信息转换成 Base64 字符串,具体格式是这样的:
- Authorization: Basic {base64_enX 1 X u O J Bcode([username]:[password])}
- Content-Type: application/json
提供一个 JS 的范例,用来转存文件:
- $.ajax~ M &0;{
- url: 'http(L V 9 p 3 L . #s)://网站域名/wp-json/brain1981/v1/catch/',
- method: 'POST',
- crossDomain: true,
- data: {
- "url": "http://xxx.xxx/abc.jpg",
- "filename":; d q n + d ( p "xyz.jpgT i K n { H h"t M /;
- },
- beforeSend: function ( xhr ) {
- //以下这行要改成自7 1 : s 4 ~ r A K己真实的用WP户名和密码,并且账号需具有d s +editor或以上权限
- xhr.setRequestHeader( 'Authorization', 'Basic 'q V ` * c Y q 1 + Base64.encode( 'usernameh ^ J H m ]:password' ) );
- Q @ n Y q2? w W A h5;,
- success: function( data, txtStatus, xhr ) {
- console.log( data )A J * # E Z m;
- console.log( xhr.status );
- }
- });
- //认证字符串的Base64编k R [ I % s码库
- var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZX u kabcdefghijklmnopqrstuvwxyz0123456u 1 : C 5789+/=",enZ ( a R \ $ P 3code:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length? _ : A c #){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&A ` L H 8 2gt;>6;a=i&63;if(isNaC \ /N(r)){u=a=64}else if(isNaN(i)){a=64}t=? w 6 &t+this.A M X . 8 O j Z &_keyStr.charAt(s)+this._keO ; _ ~ I q w IyStr.charAt(i r Q g Z d _o)+this._ke} * b [ U A 4 K }yStr.charAt(u)+this._keyStr.charAt(a)}return t},dec? u , a x 8ode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");wj @ f + x 3 ~ 7hile(f<e.length){s? s 6=this._keyStr.indexOf(e.charAt(f++)P P F [ ) V n - w);o=this._keyStr.indexOf(e.charAt* J ] W +0;f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._key$ d L m Q + tStr.indexOf(e.charAt(f++));n=s<2 h ];<2|o>>4;r=(o&aT G 6mp;1b A e 7 i5&X n ~ = F#41;<<. r 2;4|u>>2;i=(u&3)<<6|a;t=t+String.fromr y cCharCode(n);if(u!=64){t=t+String. Y ; i.fromCharCodW c D V M E Ye(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t&. l b % ? N G#125;,_utf8_encode:fuy I g ,nction(e){e=e.re! $ : } v r S : Oplace(/c / i M * j k\r\n/g,"\n");var t=&qu# i w 2 2 ,ot;";for(var n=0;n<e.length;n++&C g # . r ^ $ % 5#41;% # ( $ + S N E x3;var r=e.charCodeAt(n);if(r<128)* ~ s % U | ] @3;t+=String.fromCharCode(rh t 4 01;}else if(r>127&&r<2048){t+=String.fromCharCode/ 0 - _ + Q ;0;r&gq 9 k 0 h k U :t;>6|192);t+=String.fromCharCode(r&63|128)}else{t+=StB C ~ z z e i # 9ring.fromCj L ? 1 g @harCode(r>>12|224p k 7 m1;;t+=String.fromCharCode(r>>W G h I F;6&63|128);t+=String.fromCharCode(r&63|128)A m 7 * * G F125;}return t},_utf8_decode:functiy d , * jon(e){var t="";var n=0;var r=c1=c2=0;wX n 1 ` K } 9 E /hile(n<e.length3 j N 8 . L a41;{r=e.charx P a SC9 K E U g 7 eodeAt(D } }n);if, B c V U B p0;r<128){t+=String.fromCharCode(r` U \ J ) 1 )41;;n++}elsC c L & De if(r>191&&r<q P B h u224){c2=e.charCodeAt(n+1);t+=String.fromCharCode(&r : b 8 Z#40;r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCQ W X & ` ^odeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}retuP l 4 { o Lrn t}};