在使用 WordPress REST API 開發(fā)應(yīng)用程序的時(shí)候,我們需要上傳圖片和文件到 WordPress 媒體庫中,而 WordPress 官方文檔沒有介紹上傳圖片的方式。我們開發(fā)一個(gè)基于 React 的WordPress主題時(shí),就遇到了這個(gè)難題,研究了幾個(gè)小時(shí),我們才找到上傳圖片的方法,在這里分享出來,供有同樣需求的朋友參考。在這個(gè)主題中,有一個(gè)表單,除了需要上傳文章的標(biāo)題,內(nèi)容、還需要上傳自定義字段和圖片作為文章的特色圖像。React 實(shí)現(xiàn)這個(gè)流程的代碼量比較大,為了簡化說明代碼,我們使用 jQuery Ajax 的方式來說明。
上傳圖片文件使用的 WP-API 接口
WordPress REST API (WP-API) 有一個(gè) ‘/media’ 的端點(diǎn),我們只需要發(fā)送合適的數(shù)據(jù)到這個(gè)端點(diǎn)就可以了,而需要發(fā)送什么格式的數(shù)據(jù)到這個(gè)端點(diǎn)才能實(shí)現(xiàn)圖片上傳,WordPress 的 REST API 里面并沒有提到,我們就是卡在這個(gè)數(shù)據(jù)格式上,花了很多時(shí)間才嘗試成功。
設(shè)置 HTML5 表單 Enctype 參數(shù)
首先我們需要讓表單知道,我們需要上傳文件,給表單設(shè)置一個(gè) enctype=”multipart/form-data” 的屬性就可以了。
<form id="imageUpload" enctype="multipart/form-data">
<input type="file" id="file" />
<input type="submit" value="save file" />
</form>
Enctype 參數(shù),默認(rèn)為 “text/plain”,如果我們需要上傳圖片,一定要設(shè)置這個(gè)參數(shù)為 “multipart/form-data”,否則在第一步就不能實(shí)現(xiàn)圖片上傳。
使用 jQuery Ajax 提交表單數(shù)據(jù)
接下來,我們需要使用 jQuery 的 Ajax 方法來提交數(shù)據(jù)到 WordPress REST API,在這里需要注意的是,我們需要添加 X-WP-Nonce 信息來實(shí)現(xiàn) WordPress REST API 認(rèn)證,認(rèn)證方法我們可以采取基 Cookie 認(rèn)證或者應(yīng)用程序密碼認(rèn)證方式。
創(chuàng)建 FormData() 對(duì)象模擬一個(gè)表單
FormData 是一個(gè) JavaScript 對(duì)象,我們可以通過這個(gè)對(duì)象創(chuàng)建一個(gè)虛擬的表單提交數(shù)據(jù),然后把這個(gè)數(shù)據(jù)發(fā)送給服務(wù)器,來模擬表單提交操作,下面的操作中,我們創(chuàng)建了一個(gè)名為 imageData 的 FormData 對(duì)象,然后附加文件到 imageData 對(duì)象中,這個(gè)對(duì)象和我們點(diǎn)擊提交按鈕提交表單時(shí)發(fā)送到服務(wù)器的表單數(shù)據(jù)是一個(gè)意思。只不過這個(gè)是我們通過代碼創(chuàng)建的。
// 獲取文件對(duì)象
var fileObject = $('input#file')[0].files[0] // 或者使用原生方法獲取文件 document.getElementById("photo").files[0];
var filename = fileObject.name;
// 創(chuàng)建一個(gè)虛擬的表單,把文件放到這個(gè)表單里面
var imageData = new FormData();
imageData.append( "file", fileObject);
設(shè)置合適的 HTTP 頭才能正確提交數(shù)據(jù)
完成了上一步,如果我們直接提交文件給 REST API,API 還是會(huì)報(bào)錯(cuò),因?yàn)?API 默認(rèn)會(huì)認(rèn)為我們提交的內(nèi)容是文本。我們還需要設(shè)置一個(gè) Content-Disposition HTTP 頭,讓 API 知道我們傳輸?shù)臄?shù)據(jù)是一個(gè)文件。
$.ajax({
url: ajaxInfo.json_url + 'media?X-WP-Nonce' + ajaxInfo.nonce,
type: 'POST',
data: imageData, //這個(gè)是上一步,創(chuàng)建的對(duì)象
cache: false,
contentType: false,
processData: false,
headers: { 'Content-Disposition': 'attachment;filename=test.jpg' },
success: succes(res) // 上傳成功后,我們可以獲取附件 ID,作為文章的附件(featured_media)和文章一起提交,來實(shí)現(xiàn)設(shè)置文章特色圖像的目的
});
上面的代碼中,我們?cè)O(shè)置了上傳的文件名為 “test.jpg”, 而在實(shí)際的項(xiàng)目中,我們需要獲取用戶選擇上傳的文件名。
上傳成功后,REST API 會(huì)返回我們創(chuàng)建成功的文件的對(duì)象,我們可以獲取上傳的附件 ID,然后在接下來的處理中,把這個(gè) ID 作為文章的特色圖片(REST API 接口中的參數(shù)為 featured_media)提交到文章的 API,把上傳的圖片設(shè)置為文章的特色圖像。如果我們需要設(shè)置的不是特色圖像,也可以把圖片設(shè)置為文章的自定義字段。除了開發(fā)WordPress主題,我們還可以通過 REST API 接口開發(fā)一個(gè)手機(jī) APP 或桌面應(yīng)用來讓用戶上傳提交文件。



終于找到可以參考的代碼了。不用有沒有一次上傳多張圖片的方法?