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
:
... but that's only part of the whole story: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.
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?
It is not. As I hinted in a comment, useIMHO my Javascript is correct
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 aDocument
, then set request body tobody
, serialized, converted to Unicode, and UTF-8 encoded.Otherwise, set request body and
extractedContentType
to the result of extractingbody
.
String
is not a Document
, therefore the first option does not apply. The definition of "extracting" is found in the fetch
spec:And you can see how UTF-8 encoding of your string looks like:USVString:
Set
action
to an action that runs UTF-8 encode onobject
.Set
Content-Type
totext/plain;charset=UTF-8
.Set
source
toobject
.
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?
This is the point of theHow do I apply different headers to different parts of the HTTP message?
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
JavaScript String Array to Object
If (Key in Object) or If(Object.Hasownproperty(Key)
How to Check If an Embedded Svg Document Is Loaded in an HTML Page
Typeerror: Cannot Read Property 'Setstate' of Undefined
Angularjs - Cancel Route Change Event
How to Create a Stopwatch Using JavaScript
Can Jquery Provide the Tag Name
What Is #Auto Attribute Here and Why It Is Required
Return Index of Greatest Value in an Array
How to Sum the Values of a JavaScript Object
How to Deeply Merge Two Object Values by Keys
Render Object Properties in React
Cross-Browser Bookmark/Add to Favorites JavaScript
Create an Array with Random Values