data cant be fetched from local file in ajax [duplicate] - javascript

This question already has answers here:
"Cross origin requests are only supported for HTTP." error when loading a local file
(30 answers)
Closed 2 years ago.
[enter image description here][1]i was learning ajax . but when i tried fetching data from local file it showed me error due to cors.i tried installing allow-access control origin but it didnt work .please help me
this is my java script code
function loadData() {
// Create an XHR Object
const xhr = new XMLHttpRequest();
// OPEN
xhr.open('GET', '/data.txt', true);
// console.log('READYSTATE', xhr.readyState);
// Optional - Used for spinners/loaders
xhr.onprogress = function(){
console.log('READYSTATE', xhr.readyState);
}
xhr.onload = function(){
console.log('READYSTATE', xhr.readyState);
if(this.status === 200) {
// console.log(this.responseText);
document.getElementById('output').innerHTML = `<h1>${this.responseText}</h1>`;
}
}
// xhr.onreadystatechange = function() {
// console.log('READYSTATE', xhr.readyState);
// if(this.status === 200 && this.readyState === 4){
// console.log(this.responseText);
// }
// }
xhr.onerror = function() {
console.log('Request error...');
}
xhr.send();
// readyState Values
// 0: request not initialized
// 1: server connection established
// 2: request received
// 3: processing request
// 4: request finished and response is ready
// HTTP Statuses
// 200: "OK"
// 403: "Forbidden"
// 404: "Not Found"
}```
[this the image of output which is showing error .][2]
[1]: https://i.stack.imgur.com/4YOqJ.png
[2]: https://i.stack.imgur.com/Bh1km.png

If you want to persist data in your client, use localStorage.
If you want to download data from a data source, use a web service.You can easily create a simple web server using Node and Express, for example (plenty of resources online), but this is beyond the scope of this answer.

Related

How can we measure an XMLHttpRequest request execution time? The time server starts processig to the time response is ready

I am trying to measure the time an asynchronous http request is processed by an http server developed in nodejs. By that I mean the time from which the server informs the client starting to process the request, to the time the server finishes processing and returns the response back to the client.
So, accrding to XMLHttpRequest documentation for readyState I am under the impression that the time difference between when readyState == 3 to readyState == 4 gets me what I want. In practice I get almost 0 to be the time difference between the two. However my expectation, according to the code snippets below is to get something around to 2000+ ms.
Why is that and how can I roughly measure the processing time in practice?
Client side:
<script>
let begin;
const xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://mydomain. com/API", true);
xhttp.send();
xhttp.onreadystatechange = function () {
if (this.readyState == 3) {
begin = Date.now();
}
if (this.readyState == 4 && this.status == 200) {
console.log("Execution time (ms):" + (Date.now() - begin));
}
};
</script>
server side ( as seen, processing a request takes around 2000ms)
let http = require('http');
let url = require('url');
let server = http.createServer(function (req, res) {
reqReceived++;
let q = url.parse(req.url, true);
res.writeHead(200, {
"Content-Type": "text/html",
"Access-Control-Allow-Origin": "*"
});
setTimeout(() => {
res.end(`response is ready`);
}, 2000);
});
server.listen();
You might argue that I should have put writing the head inside the timeout callback, however it would not still make any time difference for the client to receive readyState ==3 and == 4.
The right readyState to start your timer is 1. Node.JS will send headers only when you call res.end(response is ready);
I tried your code and scan it using Wireshark:
The row #4 corresponding to the request sent by your client. The #6 is the header is sent by your server with the body.
According to MDN:
state 2 => XHR received headers from server
state 3 => Response is being loaded (if chunk)
state 4 => Response parsed.
By testing 2, 3 or 4, you'll only test the time that XHR will process the response. But "response is ready" is very short and it explain why you got 0ms everytime.
You can use the following code
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 1) console.time("count");
if (this.readyState == 4 && this.status == 200) {
console.timeEnd("count");
}
};
xhttp.open("GET", "https://mydomain. com/API", true);
xhttp.send();
}
With this, you can check the time after the request has been opened. If you want to count the total time you can move the console.time before the open function call, and you can see on the network tab (chrome browser) that the timing is near the actual timing the browser counts.
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.timeEnd("count");
}
};
console.time("count");
xhttp.open("GET", "https://mydomain. com/API", true);
xhttp.send();
}
Note: if you get near 0ms for your request make sure you have disabled the cache of your request from the network tab
From MDN, readyState = 3 means Response's body is being received. Which I interpret as the request has already processed and the client is now downloading the response.
To achieve what you want I would suggest measure the time difference from when you send the request, just above xhttp.send(), and when the readyState is 3. If it was me, I would extend it to when readyState is 4. This gives more realistic times which an end user might experience and includes the time it takes for the request to go over the network.
As a side note may be try measuring the difference between readyState=2 and readyState=4. Per MDN docs readyState is 2 when the request has been sent and the client has received the headers back, which means the connection has been successful. So, it should give accurate representation of time spent during processing on server side and will eliminate any network delays.
I would love to know your results.
I would do something like the following:
function timeFetch() {
let begin
const xhttp = new XMLHttpRequest()
xhttp.open("GET", "https://myDomain. com/API", true)
xhttp.send()
xhttp.onreadystatechange = function () {
if (this.readyState == 1) {
begin = new Date(Date.now())
}
if (this.readyState == 4 && this.status == 200) {
let end = new Date(Date.now())
console.log(
"Execution time (ms):" + (begin.getMilliseconds() - end.getMilliseconds()))
}
}
}

XMLHTTPRequest keeps looping through conditional statements?

I am trying to run a conditional statement based on the readystate of my xhr. The readystate switches to 1 after open() is called (line 2), but never changes after that. It skips over the conditionals, and nothing is sent.
I'd love to know why readystate is not changing?
var xhr = new XMLHttpRequest();
xhr.open('POST', submitUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
function1();
function2();
} else if (xhr.status === 400) {
function3();
function2();
} else if (xhr.status != 400 && xhr.status != 200) {
function5();
function6();
}
}
xhr.send(body);
})
According to your code, your observations, and the context you've provided in the comments, you've two issues:
sending form data
evaluate the response
Let's assume some basic form like this:
<form action="endpoint.php" method="post">
<input type="hidden" name="token" value="value">
<input type="submit" name="submit" value="submit">
</form>
To be able to send this form's data ourselves, we need to make sure we're intercepting the browser's default behaviour of submitting it right away as soon as the submit button is clicked (cf. also epascarello's comments):
// Intercept the onsubmit event
document.querySelector('form').onsubmit = function (evt) {
// Make sure to prevent the form from being submitted by
// the browser, which is the default behaviour.
evt.preventDefault();
// Get the form's data
let form = new FormData(evt.target);
// We're going to explicitly submitting our data
// as JSON, so make sure it actually is JSON.
let data = JSON.stringify(Object.fromEntries(form)); // https://stackoverflow.com/a/55874235/3323348
sendRequest(data); // Our submit function, which we'll define next (see below)
};
Now, we'd be able to actually send the data, and to properly handle messages and status codes send back by the server. But first, let's have a quick look at your if clauses, because they might not work the way you expect them to. Especially because state and status aren't mutually exclusive - a readyState of 4 doesn't mean the server hasn't answered with an HTTP status code denoting an error (like a 404):
if (xhr.readyState === 4) {
console.log(xhr.status); // Could be any HTTP status code
} else if (xhr.status === 400) {
console.log(xhr.readyState); // Could be any readyState besides 4
} else if (xhr.status != 400 && xhr.status != 200) {
console.log(xhr.readyState); // Could be any readyState besides 4...
console.log(xhr.status); // ...and any HTTP status code besides a Bad Request (400) and an OK (200)
}
So let's tackle that part a bit different, while the rest of your code stays the same (though wrapped in a function):
function sendRequest(data) {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/endpoint.php'); // All requests are asynchronous by default,
// so we can drop the third parameter.
xhr.setRequestHeader('Content-Type', 'application/json');
// Since we've just created a client and initialized
// a request, we'll receive notifications for states
// 2-4 only (instead of 0-4).
xhr.onreadystatechange = function () {
console.log(xhr.readyState); // Let's watch the readyState changing
// We're interested in the final result of our request only (state 4),
// so let's jump all other states.
if (xhr.readyState !== 4) {
return;
}
const status = xhr.status; // HTTP status code
const type = status.toString().charAt(0); // Get class of HTTP status code (4xx, 5xx, ...)
if ([4,5].includes(type)) {
console.log('An error occured', status, xhr.responseText);
return;
}
if (status == 200) {
console.log('OK', xhr.responseText);
return;
}
// Server answered with a status code of 1xx, 3xx, or > 200.
console.log('Unexpected response', status, xhr.responseText);
}
xhr.send(data);
}
Now, you should be able to successfully send form data (and send it as JSON) and evaluate the HTTP response status codes. Instead of using XMLHttpRequest, though, you might want to consider fetch() instead.
Misc:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#events
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
How to convert FormData (HTML5 object) to JSON
Send POST data using XMLHttpRequest

How to deal with insecure XMLHttpRequest endpoint [duplicate]

This question already has answers here:
"Mixed content blocked" when running an HTTP AJAX operation in an HTTPS page
(13 answers)
Closed 3 years ago.
I am very new to coding, and have a problem with my site. I am getting an error message that says:
Mixed Content: The page at 'ajax-utils.js:34 Mixed Content: The page at 'https://daringtrifles.github.io/courserahtmlcssjavascript/module5realsol/index.html' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://davids-restaurant.herokuapp.com/categories.json'. This request has been blocked; the content must be served over HTTPS
Here is my AJAX code. Could you guys please tell me where my mistakes are and how I could solve them?
(function(global) {
// Set up a namespace for our utility
var ajaxUtils = {};
// Returns an HTTP request object
function getRequestObject() {
if (window.XMLHttpRequest) {
return (new XMLHttpRequest());
} else if (window.ActiveXObject) {
// For very old IE browsers (optional)
return (new ActiveXObject("Microsoft.XMLHTTP"));
} else {
global.alert("Ajax is not supported!");
return (null);
}
}
// Makes an Ajax GET request to 'requestUrl'
ajaxUtils.sendGetRequest =
function(requestUrl, responseHandler, isJsonResponse) {
var request = getRequestObject();
request.onreadystatechange =
function() {
handleResponse(request,
responseHandler,
isJsonResponse);
};
request.open("GET", requestUrl, true);
request.send(null); // for POST only
};
// Only calls user provided 'responseHandler'
// function if response is ready
// and not an error
function handleResponse(request,
responseHandler,
isJsonResponse) {
if ((request.readyState == 4) &&
(request.status == 200)) {
// Default to isJsonResponse = true
if (isJsonResponse == undefined) {
isJsonResponse = true;
}
if (isJsonResponse) {
responseHandler(JSON.parse(request.responseText));
} else {
responseHandler(request.responseText);
}
}
}
// Expose utility to the global object
global.$ajaxUtils = ajaxUtils;
})(window);
Your mistake is here:
request.open("GET", requestUrl, true);
requestUrl is http://davids-restaurant.herokuapp.com/categories.json i guess. You need to change that URL just a bit.
Change your Request URL from
http://davids-restaurant.herokuapp.com/categories.json
to
https://davids-restaurant.herokuapp.com/categories.json.
Just add an "s" to your http -> https
Now it should work.

access XMLHttpRequests send(data) in PHP backend

I have an XMLHttpRequest sending data to a PHP backend.
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
// Resolve the promise with the response text
resolve(req.response);
}
else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};
// Handle network errors
req.onerror = function() {
reject(Error("Network Error"));
};
// Make the request
req.send('query=messages'); // <-- i want to access this in php
i tried
print_r($_GET) and print_r($_REQUEST) but neither works.
anyone knows how to access this data?
You can only send data through the XMLHttpRequest.send()-method for POST-requests, not GET.
For GET-requests, you need to append the data to the url as query string.
url += "?query=message";
Then you can retrieve the data with PHP using:
$message = $_GET['query'];
More info: http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp

Setting up CORS not working

I have the following headers set on the server
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT");
response.addHeader("Access-Control-Allow-Headers","X-Custom-Header");
And i want to use the POST method to access a web service and send data to it but the problem is my setting up with the server is causing problems
I used the following method
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Safari/Firefox.
xhr.open(method, url, true);
}
else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
and based on this object
url = "http://myurl.do";
var xhr = createCORSRequest('POST', url);
if (!xhr) {
alert('CORS not supported');
return;
}
var params = "name=pari123&action=initaction&gameId=slotreel3";
xhr.setRequestHeader('Content-Type', 'application/text/plain');
if(xhr.readyState == 4 && xhr.status == 200)
{
alert('Tested OK')
xhr.send(params);
}
else
{
alert('status not 200 or xhr is not ready');
}
// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
alert('Response from CORS request to ' + url + ': ' + text);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
But always it alerts a message saying 'status not 200 or xhr is not ready' i am not able to proceed any one if you know please kindly help!
when i print the xhr.readyState its printing a value of 1
if(xhr.readyState == 4 && xhr.status == 200)
This check must be placed in the onreadystatechange event handler. You obviously cannot have a 200 status code or a "finished" request before actually sending it.
What you wanted is probably this:
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
alert('Tested OK');
var text = xhr.responseText;
alert('Response from CORS request to ' + url + ': ' + text);
}
};
xhr.send(params);
If you want an else case to check for errors remember that you still need to check for xhr.readyState == 4. You don't want your error-handling code to run for other readyStates.
There is no need for the onload event - when you get readyState == 4 you know the request has finished.
There can be several issues here.
I observed that different browsers implement CORS differently. My experience is based on Firefox and Google Chrome. For example, I had to add a special header on server side, so that Firefox would make the preflight (OPTIONS) request and the actual request (GET,PUT etc.) using one connection as Google Chrome does it. You would have to add on the server side:
response.addHeader("Keep-Alive", "timeout=2, max=100");
response.addHeader("Connection", "Keep-Alive");
I also noticed that some browsers do not like the wildcard ("*") in the CORS headers. A workaround for the line
response.addHeader("Access-Control-Allow-Origin", "*");
would be to return the origin of the request and not a wildcard.
However, there could be also other problems and we would need more details. For example, does the request work when the server is hosted on the same domain (i.e. the problem might not be related to CORS). What server are you using?
xhr.send(); needs to be just after the call to xhr.open(); does it not? Status 1 means the request has not been sent yet, it'll never get to status 4 unless you actually send the request..

Categories