XMLHttpRequest loads XML from local server but not from external server? - javascript

I've made various attempts to load XML from external servers, but without success.
The first example loads the XML perfectly when I have the XML document on my server, but not when I try loading the same XML from the external server.
The second example is loading XML from on an external server, but the data that loads on my page doesn't resemble XML.
Am I missing something in my XMLHttpRequest, or is this the Cross Origin problem?
EDIT: The second example was solved by changing responseText to responseXML, however the first example already has responseXML and yet it doesn't work. Why won't the first example function in the same manner as the second example?
first example
var n = document.getElementById("search");
n.addEventListener("keyup", function(event) {
event.preventDefault();
if (event.keyCode === 13) {
document.getElementById("myButton").click();
}
});
function loadDoc(url, cFunction) {
var xhttp;
xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
cFunction(this);
}
};
xhttp.open("GET","https://www.w3schools.com/xml/books.xml", true);
xhttp.send();
}
function myFunction(xhttp) {
var a = n.value;
var xmlDoc = xhttp.responseXML;
const { value } = search;
const foundState = [...xmlDoc.querySelectorAll('title')].find(possibleMatch => possibleMatch.textContent === value);
const unit = foundState.parentElement;
console.log(unit.innerHTML);
document.getElementById("titleNode").innerHTML = unit.children[0].textContent;
document.getElementById("authorNode").innerHTML = unit.children[1].textContent;
document.getElementById("yearNode").innerHTML = unit.children[2].textContent;
}
<input type="text" name="search" id="search" placeholder="type 'r'" list="searchresults" autocomplete="off" />
<datalist id="searchresults">
<option value="Everyday Italian">001</option>
<option value="XQuery Kick Start">010</option>
<option value="Learning XML">110</option>
<option value="Harry Potter">101</option>
</datalist>
<button id="myButton" type="button"
onclick="loadDoc('https://www.w3schools.com/xml/books.xml', myFunction)">Submit
</button>
<p>Title node: <span id="titleNode"></span></p>
<p>Author node: <span id="authorNode"></span></p>
<p>Year node: <span id="yearNode"></span></p>
second example
function loadDoc(url, cFunction) {
var xhttp;
xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
cFunction(this);
}
};
xhttp.open("GET", "https://data.cityofnewyork.us/api/views/kku6-nxdu/rows.xml", true);
xhttp.send();
}
function myFunction(xhttp) {
document.getElementById("demo").innerHTML =
xhttp.responseXML;
}
<div id="demo">
<h2>The XMLHttpRequest Object</h2>
<button type="button"
onclick="loadDoc('ajax_info.txt', myFunction)">Change Content
</button>
</div>

Your hunch is correct, this is the Same-Origin Policy in action! Some servers are set up to allow Cross-Origin Resource Sharing (CORS), but that is pretty rare. If you would like to set up one of your websites/servers to allow another Ajax request access, you can follow this MDN guide.
Edit: Scott Marcus is correct about your code.
About your second question:
I ran your code and got this error in the console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.w3schools.com/xml/books.xml. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
w3schools does not have CORS enabled.
Take a look at this thread and the links posted there to find a way to circuimvent the Same Origin Policy.

Related

AJAX POST XHR Failure - Why is this not working?

I am pulling my hair out here. I have checked several other posts that were related to issues with POST and AJAX, but none I found were helpful. I cannot figure out why this is not working.
I keep getting the error:
Uncaught TypeError: Cannot read property 'value' of null
at loginRequest (loginRequest.js:3)
at HTMLButtonElement.onclick (main.html:325)
Here is the form on the ".html" page (minus my class calls):
<form id="loginform">
<div>
<label for="login_userid"><b>Username</b></label>
<input id="login_userid" type="text" placeholder="Enter Username" name=login_userid"
autocomplete="username" required>
<label for="login_psw"><b>Password</b></label>
<input id="login_psw" type="password" placeholder="Enter Password" name="login_psw"
autocomplete="current-password" required>
<button onclick="loginRequest()">Login</button>
</div>
Then here is the ".js: file, which I am declaring in the head of the ".html" file:
function loginRequest() {
{
var login_userId = document.getElementById('login_userId').value;
var login_ps = document.getElementById('login_psw').value;
const bcrypt = dcodeIO.bcrypt;
var login_psw = bcrypt.hashSync(login_psw, 12);
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 8 and older
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var data = "login_userId=" + login_userId + "&login_psw=" + login_psw;
xhr.open("POST", "https://dfs-coach.com/assets/php/login.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
xhr.onreadystatechange = display_data;
function display_data() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
//alert(xhr.responseText);
document.getElementById("login_result").innerHTML = xhr.responseText;
} else {
alert('There was a problem with the request.');
}
}
}
}
}
Note: bcrypt.js is also declared in head, after loginrequest.js.
The '#login_result' element is at the top of the html page (login form opens in a modal)
I cannot figure out where my screw up is with this one.. I know it is going to be something I did, i.e., a syntax error, scope issue,. etc... but I cannot find it.
The error returns that the username is null, which is difficult to believe since A: I type it in before hitting the button to trigger the function, and B: it is a required field, so I cannot hit the button if it is not filled.
However, I get that TypeError from above and then the browser tacks the correct info onto the end of the current URL in plain text and it appears in my address bar. This happens both locally and from an active web server.
The Dev Panel shows this as an "Info" entry:
Navigated to
https://www.dfs-coach.com/main.html?login_userid=MyUsernm&login_psw=PwformyUser
(Info typed into form: 'MyUsern' and 'PwformyUser')
Feel free to see the live demo of this error: https://dfs-coach.com/main.html
I would appreciate any help at all on this one.
Thanks
P.S.: I have also tried using both '.innerHTML' and innerText' instead of 'value' on the Dom elements, and also sending the form data as FormData and json. All to no avail.
There two issues which can easily be fixed I found in the code snippet in the question:
1.
In the 1st line of the function you tried to find an element by the id: login_userId, however the element is named login_userid in the HTML code, Make sure that the capitalization is the same otherwise document.getElementById won't find the correct element
2.
Another small mistake in the 4th line of the code where you try to hash login_psw bcrypt.hashSync(login_psw, 12); however that variable does not exist yet. I believe what you are trying to do is hash the login_ps variable made a couple lines earlier
I also suggest you to put the function immediately after the xhr.onreadystatechange
Code that should work:
<body>
<script src="https://cdn.jsdelivr.net/npm/bcryptjs#2.4.3/dist/bcrypt.min.js"></script>
<div id="loginform">
<div>
<label for="login_userid"><b>Username</b></label>
<input id="login_userid" type="text" placeholder="Enter Username" name=login_userid"
autocomplete="username" required>
<label for="login_psw"><b>Password</b></label>
<input id="login_psw" type="password" placeholder="Enter Password" name="login_psw"
autocomplete="current-password" required>
<button onclick="loginRequest()">Login</button>
</div>
</div>
</body>
<script>
function loginRequest() {
{
var login_userId = document.getElementById('login_userid').value;
var login_ps = document.getElementById('login_psw').value;
const bcrypt = dcodeIO.bcrypt;
var login_psw = bcrypt.hashSync(login_ps, 12);
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 8 and older
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var data = "login_userId=" + login_userId + "&login_psw=" + login_psw;
xhr.open("POST", "https://dfs-coach.com/assets/php/login.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
xhr.onreadystatechange = function display_data() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText);
} else {
alert('There was a problem with the request.');
}
}
}
}
}
</script>

XML HTTP Request not working in event handler functions

I am trying to load weather data using a simple http request. The actual request is set up properly, as it works perfectly when not called, but rather when the program just runs it upon loading. However, when I place the code in a function called from an onclick or onsubmit event, the readyStatus foes directly to 4, and the status code stays at 0, and that is it. The request does not get executed. Is there something I do not know about setting up an http request in an event handler function? Or is there a mistake in this work that I have not realized. The relevant code is directly below:
<form class="form-inline">
<div class="form-group">
<label for="city">City: </label>
<input type="city" class="form-control" id="city" placeholder="Enter City">
</div>
<div class="form-group">
<label for="state">State: </label>
<input type="state" class="form-control" id="state" placeholder="Enter State">
</div>
<button type="submit" class="btn btn-lg btn-info" id="submit" onclick="get_data()">Submit</button>
</form>
And the get_data function, where the http request is set up, is below:
function get_data(){
request = new XMLHttpRequest();
request.open("GET", "http://api.wunderground.com/api/31c6aa45ad6072ac/conditions/q/MA/Boston.json", true);
request.onreadystatechange = function(){
alert(request.readyState);
alert(request.status);
if (request.readyState == 4 && request.status == 200) {
console.log(request.responseText);
}
}
request.send();
}
Mixed content warning with the current code. Changing the url from http to https solves it. Check this snippet, the http button and the https button change the url from/to https. The problem exhibited from http match your reported issue.
function get_data(s){
request = new XMLHttpRequest();
url = "http://api.wunderground.com/api/31c6aa45ad6072ac/conditions/q/MA/Boston.json";
if (s) url = "https://api.wunderground.com/api/31c6aa45ad6072ac/conditions/q/MA/Boston.json";
request.open("GET", url, true);
request.onreadystatechange = function(){
alert(request.readyState);
alert(request.status);
if (request.readyState == 4 && request.status == 200) {
console.log(request.responseText);
}
}
request.send();
}
<button onclick='get_data()'>http</button>
<button onclick='get_data(1)'>https</button>
I simplified the button, and changed the alerts to console.log(s) on jsbin, and it's working properly (IMO):
function get_data() {
console.log('running');
request = new XMLHttpRequest();
request.open("GET", "http://api.wunderground.com/api/31c6aa45ad6072ac/conditions/q/MA/Boston.json", true);
request.onreadystatechange = function () {
console.log(request.readyState);
console.log(request.status);
request.readyState == 4 &&
request.status == 200 &&
console.log(request.responseText);
}
request.send();
}
<button onclick="get_data()">Submit</button>
http://jsbin.com/cegifi/edit?html,js,console,output
Figured it out, it was the fact that the button was of type submit and not button, so that it would resubmit the page with false information. Thanks for everyone's help!!

How to use CORS?

I am trying to implement Ajax calling and i came across the follwing code:
<!DOCTYPE html>
<html>
<body>
<p id="demo">Let AJAX change this text.</p>
<button type="button" onclick="loadDoc()">Change Content</button>
<script>
function loadDoc() {
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("demo").innerHTML = xhttp.responseText;
}
}
xhttp.open("GET", "www.google.com", true);
xhttp.send();
}
</script>
</body>
</html>
I am tring to access the URl but ended up in error saying "XHR cannot load".
I know it is something related with CORS. I went through several pages but i am finding it difficult to understand the issue. can somebody please explain and resolve this issue?? Will be helpul
Google dont allow cross domain access to their search engine. Your method seems ok, its just the url you are trying to access doesn't allow your domain.
Try it with a file hosted on your local machine

Filling the details in a third party website automatically

I have a page with an iframe (displaying a third party website) in it. On click of a button in my page, username which I feed in, should go and get set in that third party website, from my iframe. I have been trying this for a while and have read about 'Same Origin Policy' and thus have been trying to use 'CORS(Cross-Origin Resource Sharing)'. I don't know if whatever am trying is allowed, but this is what I have done till now.
I do not know how to proceed from here.
<iframe name="ifr" id="ifr" height="200" width="200" src="https://somethirdPartyWebsite.com"/> </iframe><br/>
<input type="submit" id="submit" onclick="validate()" />
<script type="text/javascript">
function validate(){
var request = createCORSRequest("get", "https://ala.kcpl.com/ala/mainLogin.cfm");
alert("request-->"+request);
if (request){
request.onload = function() {
alert("In onload...");
};
request.onreadystatechange = stateChanged();
request.send();
}
}
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
function stateChanged(){
alert("State Changed..");
}
**OUTPUT : **In IE, am getting alert("request-->"), alert("State Changed"), alert("In load").
In Firefox, am getting alert("request-->"), alert("State Changed").
Question: What am I to conclude from this and how do I go forward and set the value in the text field of the third party website, which is present in the iframe ifr
I think I need to do something like
$("#ifr").contents().find('#inputUsername').val()="ValueToEnter".
Not familiar with UI coding, please don't frown :)
You can't. Same-origin policy doesn't allow this.
CORS should be set on the server-side, it's not something that you can configure client-side.

POST XMLHTTPRequest in Javascript

I'm not very familiar with APIs in general, but don't let that discourage you from answering this question ;)
I'm trying to pull data using the XMLHTTPRequest object. I was originally going to use a WSDL file, but the API I'm using does not have one. For some reason, when I'm trying to get the response displayed in an HTML file, nothing comes across, not even the error that it didn't connect. The api also requires the use of POST.
Here's the javascript:
window.onload = function startCall() {
var http = new XMLHttpRequest();
var url = "https://api.domain.com";
var params = "Version=2.00&ApiKey=111111111111111111&CallID=001";
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", "226");
http.setRequestHeader("Host", "api.domain.com");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
function sendToHtml(url, 'target') {
if (req.readyState == 4) {
if (req.status == 200) {
document.getElementById('target').innerHTML = req.responseText;
}
}
else {
document.getElementById('target').innerHTML=" Error:\n"+ req.status + "\n" +req.statusText;
}
}
}
And here's the HTML
<html>
<head>
<script type="text/javascript" src="call.js"></script>
</head>
<body>
<span onload="startCall" id="target">
</span>
</body>
</html>
Thankyou for any help
POST requests between domains are restricted so browser will not allow it.
There is option to enable it (CORS) by sending correct Access-Control-Allow-Origin, but it have to be done on API server.

Categories