Sending cross-domain ajax requests without jQuery - javascript

I have the following code:
function ajax(callback, requestString){
console.log("basic ajax sending");
var xmlhttp;
// compatible with IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
callback(xmlhttp.responseText); //we got a response
}
}
xmlhttp.open("GET", requestString, true);
xmlhttp.send();
}
//Here: code to be able to use that function repeatedly.
it works great if used on my node.js server's domain, problem is that I am developing an API, and requests have to be sent cross-domain. These requests(requestString) are just one string that is formatted something in the likes of: "http://example.com/r?a=a" + "&b= b" if that matters. I get the following error: XMLHttpRequest cannot load. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource. I did see a solution with jQuery and jsonP but I don't want to shove jQuery to my clients, so I have to find a good solution...
Thank you for your time!

But jsonP can work without jQuery. For example:
var CallbackRegistry = {};
function scriptRequest(url, onSuccess, onError) {
var scriptOk = false;
// generating JSONP function name
var callbackName = 'cb' + String(Math.random()).slice(-6);
// add name in url
url += ~url.indexOf('?') ? '&' : '?';
url += 'callback=CallbackRegistry.' + callbackName;
CallbackRegistry[callbackName] = function (data) {
scriptOk = true;
delete CallbackRegistry[callbackName];
onSuccess(data);
};
function checkCallback() {
if (scriptOk) return;
delete CallbackRegistry[callbackName];
onError(url);
}
var script = document.createElement('script');
// for IE
script.onreadystatechange = function () {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
this.onreadystatechange = null;
setTimeout(checkCallback, 0);
}
}
script.onload = script.onerror = checkCallback;
script.src = url;
document.head.appendChild(script);
}
Now you can get response through cross domain just call
function afterSuccess(data) {
alert('Success' + data);
}
function afterError(data) {
alert('Error' + data);
}
scriptRequest(url, afterSuccess, afterError);

Well, on the server side you could change the Access-Control-Allow-Origin for the end point to Access-Control-Allow-Origin: *, ...note this will match anything. Depending on your server framework there is definitely a method to whitelist certain urls to access your endpoint. Hope that helps

Related

Cant send XMLHttpRequest in Android 11

Im using a WebView in Android studio and running it on a Physical Zebra TC52 Device which runs Android 11. In the HTML I have a button that onclick calls the getData function. The XMLHTTPRequest always returns the status 0 and the response Text is empty.
I have tried this code on https://jsfiddle.net/ and it worked fine. I dont know what the issue is
function displayData(data) {
document.getElementById('size_value').textContent = "10.5cm x 7cm";
document.getElementById('colour_value').textContent = "Red";
document.getElementById('material_value').textContent = "Metal";
document.getElementById('send_date_value').textContent = "2022-12-25";
document.getElementById('table').style.visibility = "visible";
}
function loadJSON(path, success) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
document.getElementById('table').style.visibility = "visible";
document.getElementById('status_value').textContent = xhr.status;
document.getElementById('content_value').textContent = xhr.responseText;
if (xhr.status === 200) {
success(JSON.parse(xhr.responseText));
}
}
};
xhr.open('GET', path, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send();
}
function getData() {
//this will contain an API call for the data
loadJSON("https://catfact.ninja/fact", displayData);
}
I have tried the code on https://jsfiddle.net/ and it worked.
I would like to call an API and get the JSON Data in return in order to fill it into the HTML fields
You need to add internet permission to you android app:
<uses-permission android:name="android.permission.INTERNET" />
https://developer.android.com/training/basics/network-ops/connecting

Why does 1 out of 10 of my requests returns CORS error in the browser

I currently have a script that makes an ajax request using XMLHttpRequest(). The essence of the script is to keep track of certain analytics and here's how it was implemented.
Adds an event listener and sends data to start_tracking_analytics script
document.addEventListener('DOMContentLoaded', function(){
try{
//url to send data to
var url = 'https://subdomain.domain.com/start_tracking_analytics.php?key='+tracker_key;
//host name
var host = location.protocol + '//' + location.hostname
//send data
sendAnalytics(url, host);
setTimeout(function(){
setInterval(function(){
try{
sendUpdateAnalytics();
}catch(e){
}
}, 7500);
}, 1000);
}catch(e){
}
});
Here's how the sendAnalytics function is implemented
function sendAnalytics(url, host){
try{
var createCORSRequest = function(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};
var method = 'POST';
var xhr = createCORSRequest(method, url);
xhr.onerror = function() {
// Error code goes here.
};
xhr.send();
}catch(e){
//...
}
}
Here's how sendUpdateAnalytics was implemented. Note: This gets triggered at intervals
function sendUpdateAnalytics(){
try{
//url to send data to
var url = 'https://subdomain.domain.com/end_tracking_analytics.php?id='+tracker_session_id;
//current host
var host = location.protocol + '//' + location.hostname
//send the data
sendData(url, host);
}catch(e){
}
}
Now, to the backend (response) script. i.e - start_tracking_analytics.php && end_tracking_analytics.php
On both scripts, I had this headers set
//GET variables
$host = $_GET["host"];
$key = $_GET["key"];
//set header for CORS
header("Access-Control-Allow-Origin: $host");
header("Access-Control-Allow-Credentials: true");
//I Do all of my computations here and echo an integer
echo 1;
The problem: 1 out of 10 requests made to end_tracking_analytics returns CORS error
Access to XMLHttpRequest at 'https://subdomain.domain.com/end_tracking_analytics.php?id=1&host=https://www.hostUrl.com&key=XXXXX' from origin 'https://www.hostUrl.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I really do hope this is explanatory and will be happy to provide more details if it's not. Any idea why this could be happening?

Why is this JSON query not working?

I am so confused at the moment, as to why this will not work.
<div id="result" style="color:red"></div>
and
var getJSON = function(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
resolve(xhr.response);
} else {
reject(status);
}
};
xhr.send();
});
};
getJSON('https://www.eobot.com/api.aspx?coin=DOGE&json=true').then(function(data) {
alert('Your Json result is: ' + data.DOGE); //you can comment this, i used it to debug
result.innerText = data.DOGE; //display the result in an HTML element
}, function(status) { //error detection....
alert('Something went wrong.');
});
It's exactly the same as: http://jsfiddle.net/RamiSarieddine/HE2nY/1/ but yet that works..
Edit: For the sake of clarity, the script is supposed to take the content at the url (within the DOGE element) and display it within
<div id="result" style="color:red"></div>
I tested it and i get below error, Which means when you try to get the json from https://www.eobot.com/api.aspx?coin=DOGE&json=true , its blocked from receiving the data due to cross browser rules.
No 'Access-Control-Allow-Origin' header
How to fix it ,
You must own https://www.eobot.com and run this script on www.eobot.com , Else you cant get the json due to cross domain policy.Ask the owner to whitelist your domain in his allow-origin header.

same domain xmlhttprequest access denied ie8

I'm fairly new to the world of web development and am trying to read a txt file in internet explorer 8 and compare it to source code of a website to see if they are equal. This is so I can work out if the web page is functioning correctly.
I managed to get the source code with an xmlhttprequest and have tried the same to get the text file (which is in the same domain as my web page) and I am getting an access denied error.
After some research I can see that cross-domain xmlhttprequests won't work but that's not what I'm trying to do so I'm not sure how to proceed.
Having run the same code in Firefox(current version). It will read the file but not the web page!
I don't mind which of the two browsers I end up using but at the moment each does half of what I want it to.
my code is:
function source1(){
xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET", "http://website",true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
document.getElementById('textzone').value = xmlhttp.responseText
var inputString = xmlhttp.responseText;
alert(inputString);
comparison(inputString)
}
}
xmlhttp.send(null)
}
function comparison(inputString){
xmlhttp1=new XMLHttpRequest();
xmlhttp1.open("GET", "comparisondoc.txt", false);
xmlhttp1.onreadystatechange=function() {
if (xmlhttp1.readyState==4) {
var compareString = xmlhttp1.responseText;
alert(compareString)
if(inputString==compareString){
alert("Strings are equal");
}
}
}
xmlhttp.send(null)
}
All I need to know is why either the file won't open in ie8, or why the website source code shows up blank (in the alert) in firefox. Any help would be appreciated.
It could be a browser support issue.
Try the following code to initialize your XMLHttpRequest :
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
}
Check your comparison function. You should you xmlhttp1 instead of xmlhttp at 2 places
function comparison(inputString){
xmlhttp1=new XMLHttpRequest();
xmlhttp1.open("GET", "comparisondoc.txt", false);
xmlhttp1.onreadystatechange=function() {
if (xmlhttp1.readyState==4) {
<!--alert(xmlhttp1.responseText)-->
var compareString = xmlhttp1.responseText;
alert(compareString)
if(inputString==compareString){
alert("Strings are equal");
}
}
}
xmlhttp1.send(null)
}
Try to add the if(xmlhttp.status == 200) { } stuff. Remember both of these are looping through status' "AND" readystates.
Technically you could be erroring somewhere (I'd rather not speculate on) halting progress to next request or whatever without the status check.
Also you "should" try other request techniques. ie.. xmlhttp.onreadystatechange = function(){itsReady(inputString)}; // we keep this line short and simple calling to another func that contains your status and readystate checks, response stuff, and more func.
On a pretty normal run the Loop looks like:
hi rdySte:1///status 0////////
hi rdySte:2///status 200////////
hi rdySte:3///status 200////////
hi rdySte:4///status 200////////
I ran into a lot of weird issues trying the long onreadystatechange = function (){ ... All stuff..} I successfully run a crazy set of request functionalities using the short onreadystatechange technique.
I noticed at the last minute->
is there a reason why the async flags are different between your funcs? I'd set them all to true unless you have a great reason.
This will work: (to test: 2 pages t1.php contains a num or whatever and t2.txt that has a num in sam dir as the funcs are called in)
function source1(){
var avar = 1;
xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET", "t1.php",true); // shortened f-names for ease of test
xmlhttp.onreadystatechange = function(){jsg_snd(avar)};
xmlhttp.send(null)
}
function jsg_snd(avar){
if (xmlhttp.readyState==4) {
if (xmlhttp.status == 200) {
var inputString = xmlhttp.responseText;
document.getElementById('text_zone').innerHTML = inputString;
document.getElementById('text_zone1').value = inputString;
// alert(inputString);//
comparison(inputString)
}
}
}
function comparison(inputString){
xmlhttp1=new XMLHttpRequest();
xmlhttp1.open("GET", "t2.txt", true);
xmlhttp1.onreadystatechange= function(){jsg_snd1(inputString);};
xmlhttp1.send(null)
}
function jsg_snd1(inputString){
if (xmlhttp1.readyState==4) {
if (xmlhttp1.status == 200) {
var compareString = xmlhttp1.responseText;
//alert(compareString)
if(inputString==compareString){
//alert("Strings are equal");
document.getElementById('text_zone').innerHTML += "; Ok "+inputString+"=="+compareString+"";
}
}
}
}
Now the html in your body should look like:
<tt id = 'text_go' onMouseUp="source1();" >Go!</tt>
<tt id = 'text_zone' onMouseUp="text_zone.innerHTML = '';" >Click to clear!</tt>
<input type ='text' id = 'text_zone1' onMouseUp="text_zone1.value = '';" value = 'Click to clear!' >
The extra stuf is for ___s & giggles.

AJAX Permission Denied On IE?

I'm trying to make an ajax call to an external domain that is already allowing external requests by sending Access-Control-Allow-Origin:* header, but i get Permission Denied on the xmlhttp.post() line.
Here is my code:
var xmlhttp;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseText);
}
}
xmlhttp.open("GET", "http://www.domain.com", true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send();
I believe that in IE, you still can't use XMLHttpRequest for cross domain requests. For that, you need to use XDomainRequest object. Full documentation is here. I believe the reason for introducing the separate object was to allow developers to do a compatibility test before making a request that certainly would fail with older browsers.
I believe you can only use Ajax with URL's form the same domain as your calling page. It's not the external domain that disallows the request, it's your browser's security. Take a look at Same Origin Policy
This is a way to avoid cross browser scripts - otherwise imagine you have a page where you can enter your credit card info and someone injects a script that sends information you are typing to an external site. Would be a big problem to fight.
Note :Do not use "http://domain.xxx" or "http://localhost/" or "IP" for URL in Ajax.
Only use path(directory) and page name without address.
false state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir1/dir2/page.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
true state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST','dir1/dir2/page.php', true); // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
function createAjax()
{
var ajaxHttp = null;
try
{
if(typeof ActiveXObject == 'function')
ajaxHttp = new ActiveXObject("Microsoft.XMLHTTP");
else
if(window.XMLHttpRequest)
ajaxHttp = new XMLHttpRequest();
}
catch(e)
{
alert(e.message);
return null;
}
//-------------
return ajaxHttp;
};

Categories

Resources