Sending Binary Data in JavaScript Over Http

Sending binary data in javascript over HTTP

By default, jQuery serializes the data (passed in data property) - and it means 0xFD008001 number gets passed to the server as '4244668417' string (10 bytes, not 4), that's why the server treats it not as expected.

It's necessary to prevent such behaviour by setting $.ajax property processData to false:

By default, data passed in to the data option as an object
(technically, anything other than a string) will be processed and
transformed into a query string, fitting to the default content-type
"application/x-www-form-urlencoded". If you want to send a
DOMDocument, or other non-processed data, set this option to false.

... but that's only part of the whole story: XMLHttpRequest.send implementation has its own restrictions. That's why your best bet, I suppose, is to make your own serializer using TypedArrays:

// Since we deal with Firefox and Chrome only 
var bytesToSend = [253, 0, 128, 1],
bytesArray = new Uint8Array(bytesToSend);

$.ajax({
url: '%your_service_url%',
type: 'POST',
contentType: 'application/octet-stream',
data: bytesArray,
processData: false
});

Or without using jQuery at all:

var bytesToSend = [253, 0, 128, 1],
bytesArray = new Uint8Array(bytesToSend);

var xhr = new XMLHttpRequest();
xhr.open('POST', '%your_service_url%');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.send(bytesArray);

How to send binary data in pure JavaScript?

IMHO my Javascript is correct

It is not. As I hinted in a comment, use Uint8Array, not strings, for binary data:

xhr.send(new Uint8Array([0x41, 0xFE, 0x80]));

If you already have a string... this should work:

xhr.send(new Uint8Array(Array.from('\x41\xFE\x80').map(x => x.charCodeAt(0)))

The explanation: The spec for send says:

If body is a Document, then set request body to body, serialized, converted to Unicode, and UTF-8 encoded.

Otherwise, set request body and extractedContentType to the result of extracting body.

String is not a Document, therefore the first option does not apply. The definition of "extracting" is found in the fetch spec:

USVString:

Set action to an action that runs UTF-8 encode on object.

Set Content-Type to text/plain;charset=UTF-8.

Set source to object.

And you can see how UTF-8 encoding of your string looks like:

new TextEncoder().encode('\x41\xFE\x80')
// => Uint8Array(5) [65, 195, 190, 194, 128]

Attempting to send binary data through $.ajax

You'll have to pass a type that can handle binary data well, like Uint8Arrayar

var x = new Uint8Array(1);
x[0]=128;
$.ajax({
url: "ajax.php",
type: "post",
data: x,
contentType: "application/octet-stream",
processData: false,
success: function(data, status, xhr) {
alert(data);
}
});

How do I send raw binary data via HTTP in node.js?

How do I apply different headers to different parts of the HTTP message?

This is the point of the multipart/form-data content type. A multi-part message looks like this:

Content-Type: multipart/form-data; boundary=---foo---

---foo---
Content-Disposition: form-data; name="datafile1"; filename="r.gif"
Content-Transfer-Encoding: base64
Content-Type: image/gif

// data goes here
---foo---
Content-Disposition: form-data; name="datafile2"; filename="g.png"
Content-Transfer-Encoding: base64
Content-Type: image/png

// another file's data goes here
---foo---

You probably don't want to put all this together yourself. There are a bunch of good libraries for putting together complex POSTs. For example: https://www.npmjs.com/package/form-data

passing binary data to rest-api

Sorry for late update, I solved this issue by using the same put request form the client side, as the put request don't require Vimeo access token, so you can use the same put request i mentioned above, and remove authentication from the header, like following

const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('selectedFile', new Blob([selectedFile], { type: 'image/jpg, image/png' }));
// formData.append('uploadLink', uploadLink);



const headers = {
'Content-Type': 'image/jpg, image/png',
Accept: 'application/vnd.vimeo.*+json;version=3.4',
};

try {
axios
.put(`${uploadLink}`, formData, {
headers,
})
.then((response) => {

console.log(`${uploadLink}link for upload`);
});
} catch (error) {
console.log(error);
}
};


Related Topics



Leave a reply



Submit