I'am trying to send binary chunk with XMLHttpRequest
var xhr = new XMLHttpRequest();
var bindata = 0x0f0f;
xhr.open("POST", "binary_reader.php");
xhr.send(bindata);
But this approach not works. I've tried to provide Content-type: application/octet-stream, Content-encoding headers for xhr and they don't work either. I am suspect that there is no way to compose request of such kind.
I would appreciate any help.
XMLHttpRequest.sendAsBinary is obsolete. Link
As MDN mentioned, you can directly send binary typed array:
var myArray = new ArrayBuffer(512);
var longInt8View = new Uint8Array(myArray);
// generate some data
for (var i=0; i< longInt8View.length; i++) {
longInt8View[i] = i % 256;
}
var xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.send(myArray);
Yes you can send binary data using XHR. All you need to do is set the appropriate headers and mime-type, and call the sendAsBinary method instead of the simple send method. For example:
var req = new XMLHttpRequest();
req.open("POST", url, true);
// set headers and mime-type appropriately
req.setRequestHeader("Content-Length", 741);
req.sendAsBinary(aBody);
W3C has introduced Blob type to XMLHttpRequest in the latest specification. Currently I haven't seen any implementation so far but in near future this is definitely the way to download and upload binary data with XMLHttpRequest.
The section "Handling binary data" here describes how to send and receive binary data via XMLHttpRequest.
Related
I am using JavaScript to create an API call and send it to a corresponding Asp.Net Core function.
JavaScript:
function fileSubmit() {
var data = document.getElementById("myFile").files; //it should be noted that this successfully catches the file.
var formData = new FormData();
formData.append("files", data);
var url = "http://localhost/api/Surveys/123456/Units/987654/Images";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "image/jpeg");
xhr.send(formData);
}
.Net Core:
[HttpPost]
[Route("{Id:int:min(1)}/Units/{unitId:int:min(1)}/Images")]
[ProducesResponseType(typeof(IAPIResponse2<UploadImagesResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(IAPIResponse2<UploadImagesResponse>), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> UploadImages([FromForm, Required] IList<IFormFile> files)
{
//do stuff
}
I am able to create and send the API call and it is caught by the Asp.Net function, but the files parameter is empty. The file list is successfully appended to the formData object in the JavaScript function, as far as I know.
What am I missing?
There are two problems with your JavaScript code above:
files is being sent incorrectly. If you look at the request, you'll see it's a bit confused and includes [object FileList] as part of the body.
To solve this issue, you'll want to iterate through the files and add them individually:
var files = document.getElementById("myFile").files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
formData.append("files", files[i]);
}
If you are just sending the one file, you could simplify this:
var files = document.getElementById("myFile").files;
var formData = new FormData();
formData.append("files", files[0]);
You should not set the Content-Type header when making the request.
To solve this issue, simply remove your call to setRequestHeader. The Content-Type header will be set by the XHR process to be multipart/form-data with boundaries (see the RFC for the Multipart Content-Type).
Each part starts with an encapsulation boundary, and then contains a body part consisting of header area, a blank line, and a body area.
Due to the way this is structured, the Content-Type is specified on a per-file basis. If you are interested, have a look at the request in the developer tools once you've made the changes I have detailed.
I have a button in my asp net app that when pressed I am calling a rest service that returns a bytearray.
This bytearray is actually a file that I need to start downloading in the browser when the button is pressed. How can I achieve this?
I am thinking along the lines of writing the bytearray to the response and setting the headers.
Is this thinking correct and does someone have some code samples?
---------Update on 3/25----------------
Thanks Justin but not yet what I need. Please look at this link it will return a file for download. What I need to do is have an event client side that will get this file for download without redirecting to this page. It has to be downloaded from my page and not this link.
http://ops.epo.org/3.0/rest-services/published-data/images/US/5000001/PA/firstpage.pdf?Range=1
If you check it out with Fiddler, you will see how the pdf is received as binary.
You can set the responseType as arraybuffer and access it that way. There is even a way to stream the data using onprogress events. JavaScript has come a long way.
var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // Note: not oReq.responseText
if (arrayBuffer) {
var byteArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteArray.byteLength; i++) {
// do something with each byte in the array
}
}
};
oReq.send(null);
https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Sending_and_Receiving_Binary_Data
If you mean that the webservice isn't returning binary data, and instead is JSON data like: [0,1,3,4] then that is a different issue.
As far as i know, the closest thing you can do with javascript is an ajax request that has the server parse the data as text
I want to retrieve the data contained in a text file (from a given URL) through JavaScript (running on the client's browser).
So far, I've tried the following approach:
var xmlhttp, text;
xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://www.example.com/file.txt', false);
xmlhttp.send();
text = xmlhttp.responseText;
But it only works for Firefox. Does anyone have any suggestions to make this work in every browser?
Thanks
IT works using xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); in IE older versions. Chrome, Firefox and all sensible browsers use xhr
Frankly, if you want cross browser compatibility, use jquery
its pretty simple there:
var text="";
$.get(url, function(data){text=data;//Do something more with the data here. data variable contains the response})
var xhr = new XMLHttpRequest();
xhr.open('POST', '/uploadFile');
var form = new FormData();
form.append('file', fileInput.files[0]);
xhr.send(form);
It was previously impossible to upload binary data with XMLHttpRequest object, because it could not stand the use of FormData (which, anyway, did not exist at that time) object. However, since the arrival of the new object and the second version of XMLHttpRequest, this "feat" is now easily achievable
It's very simple, we just spent our File object to a FormData object and upload it
On an html page I have an <object> that hosts a pdf.
I would need to access the binary data of the pdf via Javascript, but I cannot figure out how
to accomplish that. I get access to the object element itself but cannot think of a method for getting the data in it.
Is it possible at all?
You can not get the binary from an object tag, but you can make an AJAX request to the server and get it as ArrayBuffer by using the new responseType attribute:
var http = new XMLHttpRequest();
http.open("get", "somefile.pdf", true);
http.responseType = "arraybuffer";
http.onload = function(e)
{
if(http.response)
{
// http.response contains the file
}
};
http.send(null);
Note that this method only works in newer browsers and is obviously restricted by the Same-Origin-Policy.
Hi I'm wondering if there's anyway to stream a binary response in AJAX? This would be an ultimate solution otherwise I would need to realize the binary image to a file then stream that file to the user with a different URL.
new Ajax.Request('/viewImage?id=123', {
// request returns a binary image inputstream
onSuccess: function(transport) {
// text example
// alert(transport.responseText)
// QUESTION: is there a streaming binary response?
$('imgElem').src = transport.responseBinary;
},
onFailure: function(transport) {
// handle failure
}
});
It might not be possible to stream binary data, but you can use Ajax to retrieve binary data.
This is possible using one of two methods: Javascript Typed Arrays or an XMLHttpResponse overrideMimeType hack. Have a read of a good article on MDN – these examples are taken from there: Sending and Receiving Binary Data
The Typed Array method looks like this:
var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // Note: not oReq.responseText
if (arrayBuffer) {
var byteArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteArray.byteLength; i++) {
// do something with each byte in the array
}
}
};
oReq.send(null);
Typed Arrays are not supported in IE < 10, Firefox < 4, Chrome < 7, Safari < 5.1 and Opera < 11.6, and mobile support is shaky but improving.
The second method uses an XMLHttpRequest method called overrideMimeType to allow the binary data to be passed through unmodified.
var req = new XMLHttpRequest();
req.open('GET', '/myfile.png', false);
// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text\/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
// do stuff with req.responseText;
You get an unparsed binary string, upon which you can use var byte = filestream.charCodeAt(x) & 0xff; to retrieve a specific byte.
This is an extension to Tom Ashworth's response (which helped to put me on the right track with the issue I was facing). This allows you to just get the filestream (FileStreamResult if you are using asp.net mvc) and set it to the img src, which is cool.
var oReq = new XMLHttpRequest();
oReq.open("post", '/somelocation/getmypic', true );
oReq.responseType = "blob";
oReq.onload = function ( oEvent )
{
var blob = oReq.response;
var imgSrc = URL.createObjectURL( blob );
var $img = $( '<img/>', {
"alt": "test image",
"src": imgSrc
} ).appendTo( $( '#bb_theImageContainer' ) );
window.URL.revokeObjectURL( imgSrc );
};
oReq.send( null );
The basic idea is that the data is returned untampered with, it is placed in a blob and then a url is created to that object in memory. See here and here. Note supported browsers.
What you can do, if you are trying to generate an image on the fly, is to just do:
<img src="http://myurl/myfile.php?id=3" />
then you can send the data with the appropriate mimetype.
If you really want to send an image, then you may want to look at the HTML5 canvas tag, but I am not certain how excanvas would work with this, for being cross-platform.
You could write to the canvas, but it would be more efficient to just use the img tag.
When you call your service, you should ask for a dataType: 'binary' response. Then, you can use saveAs(FileSaver.js) to trigger the download or createObjectURL to open in new window.
But, $.ajax doesn't let you download binary content out of the box, it will try to decode your binary from UTF-8 and corrupt it. Either use a jQuery plugin to solve this problem jquery.binarytransport.js
exemplo:
$.ajax({
type: "POST",
url: $("form#data").attr("action"),
data: formData,
dataType: 'binary', //--> using jquery.binarytransport.js
success: function (response) {
// Default response type is blob
saveAs(response, "test.pdf"); //--> using FileSaver.js
let fileURL = URL.createObjectURL(blob);
window.open(fileURL); // open file in new window
}
});
Good look! :)
You can send any response you want, being it plain text, HTML, an image... whatever! It's up to you how to handle it when you receive it.
But... you cannot assign a binary image to the <IMG> src attribute. You'd better just return the URL to the image and assign that instead - well, to be honest, there are some encodings to embed images in the SRC, but they are not cross-browser so you'll want to stay away from them.
I managed to get download of binary file without corrupted data working using jQuery ajax by adding:
xhrFields: {responseType: 'blob'}