I am trying to upload images to blob storage via azure functions. Kind of struggling to get it working.
var data = new FormData();
xhr = new XMLHttpRequest();
data.append('file', file);
data.append('name', file.name);
xhr.open('POST', 'https://[blobstorage]/api/upload/foo', true);
xhr.setRequestHeader('Content-type', 'multipart/form-data;');
xhr.send(data);
The POST gets triggered in azure functions:
if (context.req.method === 'POST') {
fs.readFile(context.req.rawBody, function (err, data) {
context.log('data', data);
blobService.createBlockBlobFromText(containerName, blob, data, {contentSettings: {contentType: 'image/png'}}, function(){
context.done();
});
});
}
This adds a file to blob storage but it isnt the image unfortunatly.
I believe context.log('data', data); showsundefined in the logs. That's why you are getting zero size file. Unfortunately multipart parsing is not part of Azure Functions functionality. You can find more details here:
How to parse Multi-part form data in an Azure Function App with HTTP Trigger? (NodeJS)
Related
Using this for to generate GCS Upload signed url v4
https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/storage_generate_upload_signed_url_v4.py#L27
I have generated upload signed url using this function "generate_upload_signed_url_v4" as mentioned above and also I tried using GSUTIL as well using
gsutil signurl -m PUT service_account.json gs://<bucket>/file.png
I am working on a demo where I need to upload PDF, PNG to GCS bucket. File uploading is file. But when I preview file in GCS Storage Console and download/preview file form Link URL
PDF is fine. But PNG somehow got damaged and not opening/previewing.
I am using Chrome '81.0.4044.138'
When I further preview PNG file using text editor it contains some header content at the top of file.
i.e
------WebKitFormBoundarysZ3BDVaNOhqwENsp
Content-Disposition: form-data; name="file"; filename="test.png"
Content-Type: image/png
So if we remove this from top of file the file will open fine..
I have created a sample React project which can be accessed here
Demo: https://github.com/qaisershehzad/upload-gcs
I am using this code for file upload
` const url = "https://storage.googleapis.com//file.png.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gitlab-ci%.iam.gserviceaccount.com%2F20200521%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200521T175304Z&X-Goog-Expires=36000&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature="
const data = new FormData()
data.append('file', this.state.selectedFile)
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.onload = function (response) {
console.log('on-load', response);
};
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log("Status OK")
} else {
console.log("Status not 200")
}
}
};
xhr.onerror = function (response) {
console.log("Response error", response)
};
xhr.upload.onprogress = function (evt) {
// For uploads
if (evt.lengthComputable) {
var percentComplete = parseInt((evt.loaded / evt.total) * 100);
console.log("progress", percentComplete)
}
}
xhr.send(data);`
I also tried same thing on Android as well and facing same issue. In Png at top these header string got added which not allowing to open Png file.
Png uploading is working fine using this CURL request.
curl -X PUT -H 'Content-Type: application/octet-stream' --upload-filen file.png 'https://storage.googleapis.com//file.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gitlab-ci%.iam.gserviceaccount.com%2F20200521%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200521T175304Z&X-Goog-Expires=36000&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature='
It will be helpful if someone can help to resolve this issue.
Actually you are sending FormData which causes a problem, you will see file get uploaded but when you retrieve file its content will be different in case of image possibly image will not get rendered.
The reason why cURL is working, because you are directly sending file not FormData.
To fix this scenario directly pass the file to ajax like mentioned below:
const file = this.state.selectedFile;
ajax.setRequestHeader('Content-Type', file.type);
ajax.send(file); // direct file not FormData
In my react app, I have a file object and I want to upload this file to google drive.
I tried to use window.URL.createObjectURL, but the uploaded file on google drive is HTML code of my site instead of the file "f.mp4".
Is there anybody know how to upload file object to google drive in browser????
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.onload = function () {
let gDoxBlob = xhr.response;
let file = new File([gDoxBlob], "f.mp4", {
type: 'video/mp4'
})
let newUrl = window.URL.createObjectURL(file);
console.log(url, newUrl.slice(5))
gapi.savetodrive.render('savetodrive-div', {
src: newUrl.slice(5), // to remove 'blob:'
filename: 'file',
sitename: 'site'
});
}
xhr.send();
For more explanation,
The 'url' is a download url from firebase storage.
In the case of dropbox, Dropbox.save with the 'url' worked nicely.
But because of the CORS error, google drive didn't work with 'url'
I tried to set my firebase cors policy but it didn't work, so I'm trying with file object after downloading a file from the 'url'.
I want to make a http file upload server with nodejs, not using form.
I've seen many fileupload examples with form.
But I need a server code that can receive files when called by api format.
For example,
Server side is nodejs (What I'm curious)
Client side is javascript(XmlHttpRequest), C#, python,.... whatever.
When client called api for fileupload, to receive files at server side, how can I do?
Use FormData.
var formData = new FormData();
formData.append("username", "Groucho");
formData.append("accountnum", 123456); // number 123456 is immediately converted to a string "123456"
// HTML file input, chosen by user
formData.append("userfile", fileInputElement.files[0]);
// JavaScript file-like object
var content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var blob = new Blob([content], { type: "text/xml"});
formData.append("webmasterfile", blob);
var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);
See more from here: https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
I am trying to send pdf file from my express server using the client when requested like this:
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=test.pdf');
fs.createReadStream('test.pdf').pipe(res);
And then on the client side I am trying to download it by taking the resulting string converting it to a url and downloading from there.
var blob = new Blob[pdfString], { type: 'application/pdf' });
var url = window.URL;
var downloadUrl = url.createObjectURL(blob);
However the resulting file is two empty pages and I beleive think it might be because the resulting file is url is to large? If anyone could figure out whats wrong here or tell me of a better way to do it that would be awesome.
I was able to figure it out using XMlHttpRequest:
var req = new XMLHttpRequest();
req.open('GET', path , true);
req.responseType = "arraybuffer";
req.onload = (event) => {
downloadPdf(req.response); //This is where I convert to blob
}
req.send();
I'm writing a chrome extension content script which will embed itself on some pages, and when there are certain file type links (.doc, .torrent, etc) it will download that file, and then do a file POST to a python web server which will save that file. The python server is working, and handles a normal multipart/form-data POST request, and successfully saves the file when I use the html interface I wrote for it.
I have javascript downloading the file properly:
var req = new XMLHttpRequest();
req.open('GET', 'http://foo.com/bar.torrent', false);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
var response = req.responseText;
And then when I try to create a POST request and upload it
// Define a boundary, I stole this from IE but you can use any string AFAIK
var boundary = "---------------------------7da24f2e50046";
var xhr = new XMLHttpRequest();
var body = '--' + boundary + '\r\n'
// Parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition: form-data; name="upfile";'
+ 'filename="temp.torrent"\r\n'
// Add the file's mime-type
+ 'Content-type: application/bittorrent\r\n\r\n'
+ response + '\r\n';
//+ boundary + '--';
xhr.open("POST", "http://python.server/", true);
xhr.setRequestHeader(
"Content-type", "multipart/form-data; boundary="+boundary
);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
alert("File uploaded!");
}
xhr.send(body);
It thinks that it uploaded successfully, but when I try to open the file it says the data is corrupted. I think this is some kind of encoding issue, but I'm not 100% sure.
Any thoughts would be very helpful.
Your upload method does not work, because all binary characters are encoded as UTF-8. I posted the explanation and solution in an answer at this question.
In your case, you don't need to manually create the post data. Request the initial data in a smart way, and use the FormData object to post the binary data. For instance:
var x = new XMLHttpRequest();
x.onload = function() {
// Create a form
var fd = new FormData();
fd.append("upfile", x.response); // x.response is a Blob object
// Upload to your server
var y = new XMLHttpRequest();
y.onload = function() {
alert('File uploaded!');
};
y.open('POST', 'http://python/server/');
y.send(fd);
};
x.responseType = 'blob'; // <-- This is necessary!
x.open('GET', 'http://foo.com/bar.torrent', true);
x.send();
Note: I replaced false with true at the initial request. Avoid using synchronous XMLHttpRequest when it's also possible to asynchronously create the request.
If you don't understand the answer, here are more examples with thorough explanations:
XMLHttpRequest: Multipart/Related POST with XML and image as payload - FormData is not used, but the post data is manually created instead.
Upload a File in a Google Chrome Extension - A sample Chrome extension which uses Web Workers (with a FormData polyfill) to upload files
Google chrome rehost image extension - Scrapes an image from the page, and upload the image to imgur using a Chrome extension.