Edit: Maybe I made the question more complex than it should. My questions is this: How do you make API calls to a server from JS.
I have to create a very simple client that makes GET and POST calls to our server and parses the returned XML. I am writing this in JavaScript, problem is I don't know how to program in JS (started to look into this just this morning)!
As n initial test, I am trying to ping to the Twitter API, here's the function that gets called when user enters the URL http://api.twitter.com/1/users/lookup.xml and hits the submit button:
function doRequest() {
var req_url, req_type, body;
req_url = document.getElementById('server_url').value;
req_type = document.getElementById('request_type').value;
alert("Connecting to url: " + req_url + " with HTTP method: " + req_type);
req = new XMLHttpRequest();
req.open(req_type, req_url, false, "username", "passwd");// synchronous conn
req.onreadystatechange=function() {
if (req.readyState == 4) {
alert(req.status);
}
}
req.send(null);
}
When I run this on FF, I get a
Access to restricted URI denied" code: "1012
error on Firebug. Stuff I googled suggested that this was a FF-specific problem so I switched to Chrome. Over there, the second alert comes up, but displays 0 as HTTP status code, which I found weird.
Can anyone spot what the problem is? People say this stuff is easier to use with JQuery but learning that on top of JS syntax is a bit too much now.
For security reasons, you cannot use AJAX to request a file from a different domain.
Since your Javascript isn't running on http://api.twitter.com, it cannot request files from http://api.twitter.com.
Instead, you can write server-side code on your domain to send you the file.
Related
To start off this is what I am trying to accomplish:
I am trying to do file copies to an array of servers. There are several steps that must be completed in a specific order before and after these copies (for example, stopping IIS, backing up and clearing folders, running a bat file, etc) so they are not single operations.
To make this super easy I wrote an API in node.js that does simple tasks like copy files and folders, delete folders, etc. I then wrote a frontend in node.js using an express generator and Pug that uses javascript XMLHhttpRequests to send commands to the API depending on what I needed to do. I have the API written and running as well as the frontend. Now on to the problems:
If I have my XMLHttpRequest run in synchronous mode (example: xhttp.open("POST", url , false);) when the command is sent to the API to copy a folder if the folder takes several minutes to copy the browser freezes. Chrome displays a "Page Frozen" error. However, the job gets done correctly.
If I have my XMLHttpRequest run in asynchronous mode (example: xhttp.open("POST", url , true);) then every command gets sent to the API at once so that the fastest operation completes first and the commands are out of order. The copy will fail.
I've tried searching for a way to make it so that each operation sent from the frontend javascript has to return a SUCCESS (or 200 response) from the API before moving on to the next command but so far all I've seen is "just use synchronous". Right now that's what I'm doing. That doesn't seem like the best solution even though it works. Is there a better way to do this in a way that won't freeze the browser?
I figured this out by writing a function to handle the requests, setting a counter (for the steps of the process), and putting a switch statement in the if statement for the result. It wasn't exactly what I needed but the basics of my solution is in the answers to this question: How can I call ajax synchronously without my web page freezing
Here's what I did in case it helps anyone else who finds this question:
function myFunction (step, params, url) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
switch(step) {
case 2:
//url and params are set here, and step 2 is done here
myFunction(step, params, url);
break;
case 3:
// and so on and so forth
}
}
xhttp.open("POST", url , true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(params);
step++;
}
//kick off the function
var step = 1;
var url = "my URL to the API with call";
var parameters = "my parameters";
myFunction(step, parameters, url);
Is there any way to get the http status of the current web page from javascript?
Spent some time searching on the web, but no luck at all... Seems like it's not possible, but wanted to check with Stack Overflow for maybe some fancy workaround.
(Providing it from the server as part of the response body is not acceptable, the status is supposed to be only available via the http header)
This is not in any way possible, sorry.
Yes You can
Simply request the same page, i.e. URI, using the XMLHttpRequest. Suppose that your page on /stop.php in stop.php you may do something like:
<script>
function xhrRequest(){
console.log(this.status);
// Do some logic here.
}
function getReq(url){
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", xhrRequest);
oReq.open("GET", url);
oReq.send();
}
getReq("/stop.php");
</script>
Checkout this DEMO
🕯 Note:
You have to note that, it is a copy of the page not the page itself.
I, already, have used this solution on a page in which the server may
generate Forbidden HTTP status code when the request is come from
unauthorized IP address, so the condition here is very simple and
there is no much difference between the original and the copy page
that you have simulate its visit.
As a one liner:
fetch(location.href).then(response => console.log(response.status));
This is asynchronous, if you need a synchronous solution use XMLHttpRequest (as in the other answer) together with async: false or use async/await which feels synchronous, but is still asynchronous under the hood.
Alternatively
An approach without an extra call would need to include the status code in the page on the server side (e.g. in a meta tag), then read it on the client side via JavaScript.
Java + Thymeleaf:
<meta name="statuscode" th:content="${#response.status}">
PHP (unverified):
<meta name="statuscode" content="<?php echo http_response_code() ?>">
It is not beautiful, but you can use:
t = jQuery.get(location.href)
.success(function () { console.log(t.status) })
.error(function() { console.log(t.status) });
That When Eric says, this solution will make a new request from the same paga, and not show status of current request.
you can only check status of page loading
try:var x = document.readyState;
The result of x could be:
One of five values:
uninitialized - Has not started loading yet
loading - Is loading
loaded - Has been loaded
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded
The following code produces nothing on the html page, it seems to break down on 'status':
var get_json_file = new XMLHttpRequest();
get_json_file.open("GET", "/Users/files/Documents/time.json", true);
**document.write(get_json_file.status);**
keep in mind, that I am on a Mac, so there is no C: drive....however, this line of code does work fine:
document.write(get_json_file.readyState);
I just want to know that I was able to successfully find my json file. Perhaps, I should ask, what should I be looking for to achieve what I want ?
Another basic question about AJAX. I suggest you to read the MDN article about using XMLHttpRequest. You can't access the 'status' property until it is ready, and you haven't even called the 'send()' method, which performs the actual request. You can't have a status without making an HTTP request first. Learn how AJAX works before trying to use it. Explaining it all would be too long and this is not the place.
You can only get the status when the ajax has finished. That is, when the page was loaded, or a 404 was returned.
Because you're trying to call status straight after the request was sent (or not sent, read the P.S), you're getting nothing.
You need to make an async call, to check that status only when the request finishes:
get_json_file.onreadystatechange = function (){
if (get_json_file.readyState==4 && get_json_file.status==200)
{
alert('success');
}
}
read more at http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp
P.S as noted by #Oscar, you're missing the send().
If you want to try a synchronous approach, which would stop the code from running until a response is returned, you can try:
var get_json_file = new XMLHttpRequest();
get_json_file.open("GET", "/Users/files/Documents/time.json", false);
//notice we set async to false (developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
get_json_file.send(); //will wait for a response
document.write(get_json_file.status);
//(Credit: orginial asker)
Because of security issues you are not allowed to send requests to files on the local system, but what you could do is look into the fileReader API. (more info here)
<sidenote>
The reason that the readyState works and not status is because by defualt
readyState has a value of 0 and status has no value so it would be undefined.
</sidenote>
in my ubuntu, the path will be prefixed with file:///
i think your json file path should have file:///Users/files/Documents/time.json, because mac and ubuntu based on unix
and then you can check ajax status using #TastySpaceApple answer
if you using google chrome, don't forget to launch it with -–allow-file-access-from-files command, because google chrome not load local file by default due to security reason
I am trying to get text from a service on the same server as my webserver. The link is something like this:
http://<OwnIPadres>:8080/calc/something?var=that
This is my code:
function httpGet(theUrl)
{
alert(theUrl);
var doc = new XMLHttpRequest();
doc.onreadystatechange = function() {
if (doc.readyState == XMLHttpRequest.DONE) {
alert("text: " + doc.responseText );
document.getElementById('ctm').text = doc.responseText;
}
}
doc.open("get", theUrl);
doc.setRequestHeader("Content-Encoding", "UTF-8");
doc.send();
}
The url that i print in my first alert is the good one if i test in my browser, it is an html page with a table in it. But the alert of my text is empty? Is it a problem that the text is html?
Actually, its quite ok that your 'text' is 'html'. The problem is that using a different port counts as cross-site scripting. Therefore, your XMLHttpRequest is being stopped by the browser before it actually reaches your page across port 8080.
I'm not sure what else you're doing before and around this code snippet, but you could try an iframe call to your url to get your data, or you could add an
Access-Control-Allow-Origin: http://:8080/
in your header (however that will only get you the most modern browsers).
Finally, you could pull in a JS framework like JQuery which could help you with pulling in this service data.
I'm trying to get a Firefox plugin to read data from a HTTP get, parse the results and present them as links in a bookmark-like drop-down menu.
My quesion then is: Does anyone have any sample code that will do this?
Having never developed one myself, I'm not certain how this is typically done in Firefox plugins, but since plugin scripting is JavaScript, I can probably help out with the loading part. Assuming a variable named url containing the URL you want to request:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.onreadystatechange = function() {
if(this.readyState == 4) { // Done loading?
if(this.status == 200) { // Everything okay?
// read content from this.responseXML or this.responseText
} else { // Error occurred; handle it
alert("Error " + this.status + ":\n" + this.statusText);
}
}
};
xmlhttp.send(null);
A couple of notes on this code:
You may want more sophisticated status code handling. For example, 200 is not the only non-error status code. Details on status codes can be found here.
You probably want to have a timeout to handle the case where, for some reason, you don't get to readyState 4 in a reasonable amount of time.
You may want to do things when earlier readyStates are received. This page documents the readyState codes, along with other properties and methods on the XMLHttpRequest object which you may find useful.
Robert Walker did a great job of describing how to send the request. You can read more about Mozilla's xmlhttprequest here.
I would just add that the response would be found (using Robert's code) using
xmlhttp.responseText
(Edit - i didn't read closely enough, thanks Robert)
You didn't indicate exactly what the data was, although you mentioned wanting to parse links from the data. You could the xmlhttp.responseText as an xml document, parse out the links, and place it into a menulist or whatever you like.