facebook graph api ajax XMLHttpRequest - Null result? - javascript

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.

Related

IE11 XMLHttpRequest do not receive full data from server

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.

Native ajax call does not redirect on 302

I have been googling for hours now. I've read a dozen "answers" on Stackoverflow, all of them using jQuery.
This is the common answer...
The ajax-request will follow that redirect afaik
Well, it doesn't.
I am trying to send a PUT from a form via native JS AJAX
[Please I beg you, don't tell me to use jQuery. I found a bug in jQuery via PUT
(1) so I'm going around it]
This is my code snippet...
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(data);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
This block works great, I can POST, PUT and DELETE without issues. The server receives the data and updates the DB according to the sent METHOD just fine.
My (SLIM based) PHP, upon successful completion, returns a 302 and a URL to go to.
This process works using POSTMAN hitting the PHP, and it goes to the right page.
Opening Chrome Tools/Network, it shows that the PHP is returning a 302 and than a 200
My response object contains the full HTML for a page in the responseText property.
Funny thing is, if I hard code a bad URL,the browser goes to my 404 page fine.
Your thoughts? (Please don't ask me or tell me to use jQuery)
EDIT/ADDENDUM -----------------------
I have discovered that the redirect is using the same METHOD of the original call.
I'm doing
PUT /user/1
the Redirect is doing
PUT http://myserver.test/
This is the right place to go. Now I understand the 405.
I don't have a PUT route defined, therefore the 405.
I create a PUT route and it works in POSTMAN but still gives me a 405 in Chrome and Firefox.
I have 2 issues to solve:
1) change the METHOD on the redirect
2) figure out why the browser doesn't like the 307
I found "a" solution. I'm not sure I like it, but...
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(data);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
window.location.replace(xhr.responseURL); // <---- solution
}
};

Ajax request with JavaScript responds with 302 (Found)

I am trying to send data by Ajax with the Post method, but the answer gives me 302 (Found) and I do not know what it can be. This is my code:
function sendData(){
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log("Response" + xmlhttp.responseText);
}
}
xmlhttp.open("POST", "request.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("name="+document.getElementById('username').value);
}
and my .php file only print a message
<?php echo 'hello : ' . $_POST["name"] ?>
The 302 status code indicates that the resource you are requesting has redirected to another resource. If this is behind some authentication, or requiring a session to be active then yes, it would follow that the session timing out is responsible for the ajax resource being called to redirect to possibly a login screen maybe.
Try to use jQuery request, as it much simpler - also recommended in the above comments!
One way to get such a message is, to forget to add a / to the end of a URL, which is a "sub-directory" of the document root. As the URL your.domain/whatever and your.domain/whatever/ might not be the same. (Depending on server configuration, and the actual application serving those URLs.)
I can see, in this case you are actually POSTing to /request.php, so this might not apply, but just in case, I'd try to make that request 'by hand' and see what happens.
There are many browser plugins, that let you generate AJAX queries.

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

XMLHttpRequest receiving no data or just "undefined"

i try to make a Firefox Addon which runs a XMLHttp Request in Javascript. I want to get the data from this request and send it to *.body.innerhtml.
That's my code so far...
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://xx.xxxxx.com", true);
xhr.send();
setTimeout(function() { set_body(xhr.responseHtml); }, 6000);
Instead of receiving the data, I get "undefined". If I change xhr.responseHtml to responseText I get nothing. I don't know why I'm getting nothing. I'm working on Ubuntu 12.04 LTS with Firefox 12.0.
If you need any more details on the script please ask!
Update:
set_body Function
document.body.innerHTML = '';
document.body.innerHTML = body;
document.close();
Update SOLVED:
I had to determine the RequestHeaders (right after xhr.open):
xhr.setRequestHeader("Host", "xxx");
For following Items: Host, Origin and Referer. So it seems there was really a problem with the same origin policy.
But now it works! Thanks to all!
when you set the last param of open to true you are asking for an async event. So you need to add a callback to xhr like so:
xhr.onReadyStateChange = function(){
// define what you want to happen when server returns
}
that is invoked when the server responds. To test this without async set the third param to false. Then send() will block and wait there until the response comes back. Setting an arbitrary timeout of 6 seconds is not the right way to handle this.
This code should work:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
set_body(xhr.responseText);
}
};
xhr.open("GET", "http://xx.xxxxx.com", true);
xhr.send();
Make sure that you are getting a correct response from URL http://xx.xxxxx.com. You may have a problem with cross-domain calls. If you have a page at domain http://first.com and you try to do XMLHttpRequest from domain http://second.com, Firefox will fail silently (there will be no error message, no response, nothing). This is a security measure to prevent XSS (Cross-site scripting).
Anyway, if you do XMLHttpRequest from a chrome:// protocol, it is considered secure and it will work. So make sure you use this code and make the requests from your addon, not from your localhost or something like that.

Categories

Resources