IE11 XMLHttpRequest do not receive full data from server - javascript

I am currently working on a web application and I came across with a strange problem. The request that I send to my flask app from Google Chrome and Firefox with XMLHttpRequest works as intended but in IE11 and possibly older versions it looks like IE closes the connection before the data is fully transferred. I send post request like this:
function getData() {
var req = new XMLHttpRequest();
req.open("POST", "http://"+window.host+"/text", true);
req.responseType = "json";
req.addEventListener("readystatechange", function(e){
if (e.target.readyState == 4 && e.target.status == 200){
display(e.target.response.data);
}
});
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
req.send(JSON.stringify({"text": "some text"}));
}
and receive from flask app like this:
#app.route('/text', methods=["POST"])
def data():
if request.is_json:
if "text" in request.get_json():
for i in request.get_json()["text"]:
if not re.search(textIntegrity, i):
return jsonify({"status": "Unrecognized characters: {}.".format(i)})
break
data = reData(request.get_json()["text"])
return jsonify({"status": 200, "data": data})
else:
return jsonify({"status": "Key 'text' not found."})
else:
return jsonify({"status": "Request type is not in json format."})
In mozilla and firefox I get the full data and the XMLHttpRequest object states that the response type is json: Mozilla Response but in IE there is no response type and the reponse is cut if it is too long:
IE Response
I don't know whether it's the flask problem or the way that IE handles the request, maybe I need to add some headers to flask project but I don't know.

Use ActiveXObject objects instead of XMLHttpRequest for older IE:
if (window.XMLHttpRequest) {
// code for modern browsers
xmlhttp = new XMLHttpRequest();
} else {
// code for old IE browsers
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
I am not sure the above will solve the issue because you already have IE11 (newer version). Why don't you try AJAX call using JS frameworks and see if you get same issue.
I would say, instead of using XMLHttpRequest(), use any JS framework/library to make AJAX calls to your flask REST endpoint, because JS frameworks/libraries will take care of these kind of issues with IE. For example JQuery, AngularJS.

I ended up changing server side code and client side code a little and made the server to send json data as string and parsing it on the client side.
function getData() {
var req = new XMLHttpRequest();
req.open("POST", "http://"+window.host+"/text", true);
req.addEventListener("readystatechange", function(e){
if (e.target.readyState == 4 && e.target.status == 200){
display(JSON.parse(e.target.response));
}
});
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
req.send(JSON.stringify({"text": "some text"}));
}
#app.route('/text', methods=["POST"])
def data():
if request.is_json:
if "text" in request.get_json():
for i in request.get_json()["text"]:
if not re.search(textIntegrity, i):
return jsonify({"status": "Unrecognized characters: {}.".format(i)})
break
data = reData(request.get_json()["text"])
return json.dumps(data);
else:
return json.dumps({"status": "Key 'text' not found."})
else:
return json.dumps({"status": "Request type is not in json format."})
It maybe is just an issue about flask jsonify, the way flask handles the responses or the way IE handles the requests, I don't know, I had the opportunity to edit the server so I went with that way.

Related

XmlHttpRequest POST method fails with status code 400 in IE11

I have a React app containing a JavaScript method which posts data to a server method. This method works fine in every browser under the sun...except IE11 (shocking I know). Unfortunately IE11 support is a requirement for this project.
IIS logs reveal 400 (bad request) HTTP status codes.
I chose not to use fetch() due to its incompatibility with IE11, and I'd rather avoid resorting to external libraries like axios or jQuery for a single method for a single browser.
I attempted a few Content-Type header values (application/json and x-url-form-encoded), and also tried various other headers which may or may not be related (Pragma, CORS - even though it's not cross-origin, Cache-Control et al.).
handleSubmit(event) {
const booking = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
};
const xhr = new XMLHttpRequest();
const url = "api/Booking/AddBooking";
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify(booking));
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
this.setState({
bookingResponse: response,
showModal: true
});
}
}
event.preventDefault();
}
I know the external libraries work with IE11 so there must be a way around this with vanilla JavaScript, I just can't find what it is. Any ideas?
The issue was related to some of the variable values. I was using ES6 string interpolation (i.e. back ticks), which is unsupported in IE.

If HEAD-HTTP-Requests only fetch the HTTP-Header, why my XHR-request has a reponseText?

Today I researched about HTTP-methods and the differences between GET and HEAD in detail.
In theory I know, that HEAD only returns the HTTP header, not the HTTP body. Its useful to get information about ressources without downloading them completly.
I made a little Script using XHR to check out a HEAD-reques and tested it in Firefox 50.0.2.
http://codepen.io/anon/pen/oYqGMQ
var req = new XMLHttpRequest();
req.addEventListener("readystatechange", function () {
if (req.readyState === 4 && req.status === 200) {
alert("got response \n" + req.responseText);
}
}, false);
req.open("HEAD", location.href, true); // this is a HEAD-request, why I get a responseText?
req.send();
Why the HEAD-Request receives the complete data in the reponseText-property? I thought HEAD-Request will not receive any data of the body.
I can't see any difference between HEAD and GET.
Am I missing a point? I am using Firefox.

PHP not receiving data from XMLhttprequest

Hi I am sending data to a php script like so:
function ajax(url,data,success) {
var request = new XMLHttpRequest();
request.open("POST", url);
request.onreadystatechange = function(object) {
if(request.readyState === 3) {
success(request);
}
};
request.setRequestHeader("Content-Type","application/json")
request.send(data);
}
The data being sent is a stringifyed javascript object. The post definitely works and the object shows in the payload section in chromes dev tools. But the php script I am sending to request object is empty. The php script's content type is set to json.
Sounds like you're experiencing quite a well-known issue (some info here: PHP "php://input" vs $_POST)
You should be able to access the data with file_get_contents('php://input')

What should a proper GET request and response look like in Node.js

I am working on a small project using Node.js.
The objective is to send an HTTP Request to an array of websites and display what they return to me.
First someone helped me to figure out that I needed a specific Node.js module (XMLHttpRequest). So I "required" it after installing it with NPM. Then I instantiate it.
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
//I don't think I need this
xmlHttp.send(null);
//Log some stuff to the console, namely the "response"
console.log(xmlHttp.responseText);
console.log(xmlHttp.statusText);
console.log("Finished!");
Now I believe what this will do is send a GET message to "theUrl", and then save the response in the xmlHttp Object's responseText member.
So now I should have a response. I should be able to print that as text (console.log(xmlHttp.responseText);). What should be in this response?
I expect to get something like "200 OK" but that is nowhere in the response I get. Am I going about this in the right way?
I plan on using the Async Node.js module to send a request like this to an array of URLs, trim up their response (name of the website name, the response status code, and each of the response headers).
You can use below;
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
// responseText => response body as string
// status => 200 is OK, 404 page not found
}
};
xhr.open("GET", "yor_url");
xhr.send();
responseText: response body as string
status: 200 is OK, 404 page not found

facebook graph api ajax XMLHttpRequest - Null result?

Summary: Keep getting null response despite public data and setting callback to enable cross domain JSON. Please help!
A similar question has been answered here
Using the new facebook graph api, ajax calls returns null (empty)
but I'm not using jquery and have tried to adapt my code to reflect that answer.
I'm trying to use a simple example to test a simple xmlhttprequest handler. I have this link in my page:
<a href='javascript:loadXMLDoc(\"https://graph.facebook.com/btaylor?callback=methodname\",\"\")'>AJAX LINK</a>
The callback=methodname parameter is to enable cross domain JSON
I'm using a generic XMLhttprequest builder:
var req; // Request object
function loadXMLDoc(url,params){
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", params.length);
req.setRequestHeader("Connection", "close");
req.send(params);
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", params.length);
req.setRequestHeader("Connection", "close");
req.send(params);
}
}
}
I then have a handler :
function processReqChange(){
if (req.readyState == 4) {
if (req.status == 200) {
alert("Done");
} else {
//alert("There was a problem retrieving the data:\n" + req.statusText);
alert("Status Code = "+req.status);
alert("There was a problem retrieving the data:\n");
alert("Failed : object = "+req);
alert(req.responseXML);
alert("Failed : response = "+req.responseText);
alert("Failed : status = "+req.statusText);
}
}else{
}
}
But I keep getting a null response (statusText OK, status code 0). Any ideas?
Thanks in advance
You can't make a cross-domain ajax request. Look into whether or not they support JSONP, or use the FB.api method from their javascript SDK
http://developers.facebook.com/docs/reference/javascript/FB.api
EDIT: I didn't read your post very thoroughly when I replied.
I see that you're adding the callback name to your ajax request, which isn't going to do any good because you're still making an XHR request, so it will still fail cross-domain. You seem to be misunderstanding how JSONP works.
Normally I'd just suggest using a framework like jQuery to abstract out the work that you shouldn't have to reinvent. If you're absolutely dedicated to doing this without jQuery, start by reading the wikipedia article on how JSONP works:
http://en.wikipedia.org/wiki/JSON#JSONP
The basic idea is:
Create a script node where the src attribute looks just like the URL you're trying to request now.
The server will respond with something like : methodname({"foo": "bar"}); instead of just JSON. Since this is being requested via a script node, your browser will execute the "methodname" function and pass in the results.
implement methodname(response) function to handle the response (i.e. do the work you intended to do in processReqChange)
Remove this line and try again:
req.setRequestHeader("Connection", "close");
It sets up the connection to close automatically, often before the send is complete.

Categories

Resources