I've been all over here and https://github.com/WP-API/WP-API/ and https://wordpress.org/ and cannot find anyone talking about this. I can get it working using postman and selecting the file, however i cannot get it work submitting it as either "multipart/form" or "image/png".
I also cannot find anything detailing exactly how the request should look. I can create attachments but they're empty images of the correct size using base64 data as the post body. I feel like I'm missing something simple but cannot figure out what it is. I'm using postman to abstract out other distractions, my headers are:
POST /wp-json/wp/v2/media
Content-Type: image/png
Content-Disposition: attachment;filename=image_1.png
Cache-Control: no-cache
Authorization: Bearer {JWT_Auth_token}
body is just
{
data:image/png;base64,{base64_string_here}
}
I get a returned response like it created an attachment, but when I check in the wp admin it's an blank file, that appears to be the correct kb size but doesn't display. What am I missing???
Finally figured it out! With the help of this WP Trac issue https://core.trac.wordpress.org/ticket/41774.
So my request looks like this now:
async function uploadImageAsync(urlbase, uri, base64, token) {
let apiUrl = urlbase + '/wp-json/wp/v2/media';
let formData = new FormData();
//dynamically get file type
let uriParts = uri.split('.');
let fileType = uriParts[uriParts.length - 1];
//generate some random number for the filename
var randNumber1 = Math.floor(Math.random() * 100);
var randNumber2 = Math.floor(Math.random() * 100);
formData.append('file', {
base64,
name: `photo-${randNumber1}-${randNumber2}.${fileType}`,
type: `image/${fileType}`,
});
let options = {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
'Authorization' : 'Bearer ' + token,
'Content-Type': 'multipart/form-data',
'Cache-Control' : 'no-cache',
},
};
console.log('header options: ',options);
console.log('form-data options: ',formData);
return fetch(apiUrl, options);
}
When base64 comes in it's formatted simply as base64: {base64-string}. Not data:image/type, since that is specified in the form data. The other thing that's key here is setting the key of form to 'file'.
The original answer did not work for me, so I changed "uri: base64,
". now it's working fine
formData.append('file', {
uri: base64,
name: `photo-${randNumber1}-${randNumber2}.${fileType}`,
type: `image/${fileType}`,
});
I wanted to put my solution somewhere in case other people find it useful. I am using react-native and redux, this solution is an action within the redux framework.
export const uploadMedia = image => {
return async function(dispatch, getState) {
const { token } = getState();
const uriParts = image.uri.split('.');
const fileType = uriParts[uriParts.length - 1];
const bodyFormData = new FormData();
bodyFormData.append('file', {
base64: image.base64,
name: `photo-qa.${fileType}`,
type: `image/${fileType}`
});
try {
const request = await fetch(
'http://stagingsite.test/wp-json/wp/v2/media',
{
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/form-data; boundary=__boundrytext__'
},
body: bodyFormData
}
);
const response = await request.json();
console.log({
text: 'uploadMedia', response, request
});
} catch (error) {
return ErrorHandler(error);
}
};
};