node.js - Direct post to AWS S3 from ReactNative (iOS) with signed request -
i trying recreate heroku example of uploading user submitted images in react native, keep getting 400 errors aws.
the images ios camera roll. have uri image , base64 encoded version of image. mime type image/jpeg
. far, have set heroku stated, having trouble making file send proper shape. i've added code below clarification.
i using react-native-image-picker select images camera roll
client side code
module.exports = react.createclass({ ... openphotos() { // called on button press, opens camera roll imagepicker.showimagepicker(options, (response) => { if (response.didcancel) return; if (response.error) return alert.alert('imagepicker error: ', response.error); this.getsignedrequest(response); }); }, getsignedrequest(pickerresp) { // image uri pickerresp.uri `data:image/jpg;base64,${pickerresp.data}` var file = { uri: pickerresp.uri, // works `data:image/jpg;base64,${pickerresp.data}`, name: `${this.props.email}.jpg`, type: 'image/jpeg' }; var body = new formdata(); body.append('file', file); fetch(`${api.test_api}sign-s3?file-name=${file.name}.jpg&file-type=${file.type}`, { method: "get" }).then(response => response.json()).then(data => { alert.alert("got signed request",data.url); fetch(data.signedrequest, { method: 'put', body: body }).then(resp => resp.json()).then(data => { this.setstate({uploadedfile: true}); this.props.tosignup(); }).catch(err => alert.alert("server error", "could not upload profile photo.")) }).catch(err => { alert.alert('s3 signed request error',"look @ logs"); console.log(err); }) }, ... };
server side code
aws npm package : [aws-sdk]
// signature upload client side s3 apirouter.get('/sign-s3', function(req, res) { console.log('signing s3') const s3 = new aws.s3(); // automatically loads key , secret const filename = req.query['file-name']; const filetype = req.query['file-type']; const s3params = { bucket: s3_bucket, key: filename, expires: 60, contenttype: filetype, acl: 'public-read' }; s3.getsignedurl('putobject', s3params, (err, data) => { if(err) return console.log(err) const returndata = { signedrequest: data, url: `https://${s3_bucket}.s3.amazonaws.com/${filename}` }; console.log(returndata) res.json(returndata); }); });
fetch(`${api.test_api}sign-s3?file-name=${file.name}.jpg&file-type=${file.type}
the fetch request here adding .jpg
onto end of filename described, when try upload s3, rejected because payload doesn't match prior request. also, xmlhttprequest suggested heroku works fine file structured have it, base64 data instead (below).
var file = { uri: `data:image/jpg;base64,${pickerresp.data}`, //pickerresp.uri, type: 'image/jpeg', name: `${this.props.email}.jpg`, };
the following xml http request send image in encoded form s3, simple request or image src property can access file.
function uploadfile(file, signedrequest, url, cb) { const xhr = new xmlhttprequest(); xhr.open('put', signedrequest); xhr.onreadystatechange = function() { if (xhr.readystate === 4) { if(xhr.status === 200) { cb() } else { alert('could not upload file.'); } } }; xhr.send(file); };
Comments
Post a Comment