The following code works as expected. Open the page "https://wiki.epfl.ch/" on Google Chrome, and execute this code on the Developer console. Note: the page "https://wiki.epfl.ch/test.php" does not exists and so it fails to load, but that's not the issue.
response = await fetch("https://wiki.epfl.ch/lapa-studio/documents/DTS/laser%20tutorial.pdf");
response.text().then(function(content) {
formData = new FormData();
console.log(content.length);
console.log(content);
formData.append("content", content);
fetch("https://wiki.epfl.ch/test.php", {method: 'POST', body: formData});
})
It logs:
content.length: 57234
content: %PDF-1.3
%���������
4 0 obj
<< /Length 5 0 R /Filter /FlateDecode >>
stream
x��K��F�����;¢�
...
Go to the Developer Network tab, choose the 'test.php' page, navigate to "Requested payload:" and you can see this content:
------WebKitFormBoundaryOJOOGb7N43BxCRlv
Content-Disposition: form-data; name="content"
%PDF-1.3
%���������
4 0 obj
<< /Length 5 0 R /Filter /FlateDecode >>
stream
...
------WebKitFormBoundaryOJOOGb7N43BxCRlv
The issue is that the request file is a binary file (PDF), and the text gets "mangled". It reports a size of 57234 bytes, when the actual file size (as fetched with a wget
command) is 60248 bytes.
The question is: How to get and send the binary data, without being modified?
I tried replacing response.text()
by response.blob()
, as follows:
response = await fetch("https://wiki.epfl.ch/lapa-studio/documents/DTS/laser%20tutorial.pdf");
response.blob().then(function(content) {
console.log(content.size);
console.log(content);
formData = new FormData();
formData.append("content", content);
fetch("https://wiki.epfl.ch/test.php", {method: 'POST', body: formData});
})
Now I get this log, with the correct file size:
content.size: 60248
content: Blob(60248) {size: 60248, type: "application/pdf"}
However, going to the Developer Network tab, choose the 'test.php' page, navigate to "Requested payload:", it shows that it sends an empty payload:
------WebKitFormBoundaryYoibuD14Ah2cNGAd
Content-Disposition: form-data; name="content"; filename="blob"
Content-Type: application/pdf
------WebKitFormBoundaryYoibuD14Ah2cNGAd--
Note: The webpage I am developing is not at wiki.epfl.ch. I provide this example so that users can try it (and avoid the "Cross-Origin Resource Sharing" problem). My "test.php" page is in php and $_POST['content']
returns the content when using response.text()
, but it returns empty when using response.blob()
. So, even if it is the case that the Developer Network tab "Requested payload:" does not show binary data, this snipped is still not working.
Try this, by converting blob to DataURL string, you can send binary data without it being damaged.
response = await fetch("https://wiki.epfl.ch/lapa-studio/documents/DTS/laser%20tutorial.pdf");
response.blob().then(function (content) {
let reader = new FileReader();
reader.addEventListener("loadend", function () {
formData = new FormData();
formData.append("content", reader.result);
fetch("https://wiki.epfl.ch/test.php", { method: 'POST', body: formData });
reader.removeEventListener("loadend");
});
reader.readAsDataURL(content);
});