How to access HTTPS API from HTTP server using AJAX - javascript

I am trying to integrate an API request with jQuery but I get a "Mixed Content" error because my website is HTTP:// and the API website is HTTPS://. I dont'want to use an SSL certificate on my site. How I can communicate with the API?
This is the code I use:
jQuery(document).ready(function() {
alert("hello");
jQuery.post('http://example.net/privacy/test.php',function(data) {
alert(JSON.stringify(data));
});
});
and use:
$.getJSON('//www.mindicador.cl/api', function(data) { ... });
Is this possible? Thanks for the help.

You cannot bypass this directly.
You could work around the issue by setting up an HTTP domain that server-side just gets the content of the HTTPS site and returns it, thereby bypassing the HTTPS issues since the new domain's JavaScript would be running from an HTTP domain and so could call the HTTP endpoint.
Or you could proxy the call, by setting up (or using some existing) HTTPS endpoint, and having that endpoint call the HTTP endpoint and return the contents it gets from the HTTP endpoint. That way the JavaScript on the HTTPS domain is only ever talking to HTTPS endpoints.

Related

How to solve CORS error while fetching an external API?

I'm developing a web app in Angular 10 that works as follows:
I'm dealing with CORS issue. I do not have permission to add code to the server I'm fetching.
I want to be able to:
Fetch the website
Parse the result, and put it in my database
I'm aiming to deploy the solution on an Apache server.
Here is the CORS error I'm dealing with:
Blocking a Cross-Origin Request: The "Same Origin" policy does not
allow viewing the remote resource located at
https://wwwfrance1.CENSORED.eu.com/api/?apikey=CENSORED.
Reason: "Access-Control-Allow-Origin" CORS header is missing. Status
code: 200.
Here is what i've tried:
Using MOSIF mozilla extension (works, but not sustainable for deployment, and for some reason, when I'm ignoring the CORS security, I cannot post on my DB any more)
Adding a header in my fetching request, such as:
/******API SEACH****/
/***Global Update***/
private updateClients() {
let xmlRequestPromise = fetch('https://wwwfrance1.CENSORED.eu.com/api/?apikey=CENSORED&service=list_clients', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
}
})
.then(async response => this.clients = this.regexSearchClient(await response.text()))
return xmlRequestPromise
}
But that doesn't work either. I've verified that the header appears in the request.
How to proceed?
What is CORS ?
Cross-origin resource sharing is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. From wiki
In simple terms only an internal webserver can send Requests which are potentially dangerous to it's web server, and requests from other server's are simply blocked.
But few HTTP requests are allowed ,Few of the allowed methods are GET, HEAD, POST.
How do I resolve the issue ?
Apparently in this circumstance you cannot send a fetch request to a web server having CORS header. Instead you can do a GET request to the web server as a web server having CORS allows HTTP GET requests.
Note - If you send a GET request to a web server using angular in your browser it wouldn't work as browser's convert GET requests into fetch requests and fetch requests aren't allowed from a web server with CORS. Instead send a GET request from a webserver/local machine rather than a browser.
Create your own server and make a route which fetches that API. From your Angular application fetch that route on your server.
You have to use a package as a middleware. If you are using nodejs-framework expressjs.At first, you have to run npm install cors -force.Then add the code that is given bellow:-
const cors=require('cors')
app.use(cors({origin:true}))

Call ajax HTTP to API with Sinatra

I'm calling a service from my api built with sinatra, and I make a simple ajax call as I mention it below:
<script>
$(document).ready(function (){
seeStatus()
});
function seeStatus(){
token = $('#token').val();
$.ajax({
url: '/see/v1/status/' + token,
type: 'GET',
dataType: "script",
complete: function (response) {
var json = $.parseJSON(response.responseText);
if (json.error == 0) {
window.location.href = json.href
}
}
});
}
</script>
made a GET call and the server receives a call OPTIONS
190.141.191.102 - - [08/Mar/2018:12:31:38 +0000] "OPTIONS /see/v1/status/f4dce2eb193674cab37ff36cbaca2eb4c0355165?_=1520512306539 HTTP/1.1" 404 51 0.0133
The code of my service is not executed from the ajax method and I do not understand why? , when I try my service independently with an HTTP client it works correctly What can I do? Any help Thanks
It looks like you're having an issue with CORS (Cross-Origin Resource Sharing). It would be interesting to know where the script requesting the API and where the API itself are located. I guess they're not on the same server.
In a nutshell, CORS is a mechanism that prevents a resource on one domain to freely access a resource on another domain. Your webpage can load resource on its own domain (scripts, stylesheets, fonts, json, etc.) but by default, Javascript HTTP requests (XMLHttpRequest / fetch) use the same-origin policy by default, which means they can only request resources on the same domain.
According to the CORS dedicated page on the MDN, here's the reason for the OPTIONS request you see on the server side:
the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method"
I guess you'll have to configure CORS on your server, or make it so that the HTML file calling the API is located on the same domain as the API itself (which might not be possible).
Since you used the Sinatra tag in this question, I guess your server is written in Sinatra, in that case you can use the britg/sinatra-cross_origin gem to setup CORS rule on your API server.

Trying to retrieve JSONP from HTTP server from a HTTPS website

I have a website based on HTTPS, and I have a JS code the get data from a website based on HTTP. I get an error that the HTTP server is not trusted.
While the same code works on HTTP to HTTP. But not on HTTP to HTTPS.
This is the error:
Mixed Content: The page at 'https://www.33k.com/player/playerudan.php' was loaded over HTTPS, but requested an insecure script 'http://33k.thepuremix.net/json.xsl'. This request has been blocked; the content must be served over HTTPS.
For getting this data I use something like the following code:
var URL = "http://33k.thepuremix.net/json.xsl"
$.getJSON( URL, function( data) {
console.log( data );
});
Any idea how to fix it or make it working. Is there such a Crossdomain.xml on Icecast that I can give configure or anything else to fix it?
UPDATE:
The above links are two different websites. It is not a sub-domain matter. The links just look alike a bit. Domain A(HTTPS) wants to get JSON from domain B (HTTP).
Calling HTTP from HTTPS is blocked by design as #RoryMcCrossan mentioned in the comments (Same Origin Policy), you can either move your script from HTTP to HTTPS or make a backend script (in PHP for example) and call HTTP from it like:
JavaScript(HTTPS) -> PHP(HTTPS) -> PHP(HTTP)
JavaScript(HTTPS) <- PHP(HTTPS) <- PHP(HTTP)
Reference to creating a http request in PHP: Http Request in PHP
Here's also some info about Same Origin Policy

No 'Access-Control-Allow-Origin' header present AngularJS

I am trying to build a quick demo site that I do not have control over the server I am trying to connect to. Here is the code that I am using to build it with AngularJS. I am running the file through a simple Python HTTP Server and viewing it at localhost:8000.
var retrieveAppliances = function () {
console.log('Attempting to retrieve appliance list.');
var requestUrl = '****';
$http({
method: 'GET',
url: requestUrl,
})
.then(function (response) {
console.log(response);
});
};
retrieveAppliances();
I have read multiple places to try switching the method to JSONP but doing so resulted in a parsing error.
While I have considered trying to build a server.js file and running NodeJS with it, I am unsuccessful in learning the basics of making an AJAX request and proxying that to my app.js.
I will greatly appreciate any help that someone may be able to give me, with clear and easy to follow steps.
If you're running an Ajax call to a different origin (e.g. different host, port or protocol) and the server at that origin does not have support for cross origin requests, then you cannot fix that from your client. There is nothing you can do from the client.
If the server supported JSONP, you could use that, but that also requires specific server support.
The only solutions from a browser web page are:
CORS support on the target server.
JSONP (also requires support on the target server).
Set up your own server that you do have access to (either on your existing page domain or with CORS) and then have that server get the file/data for you and proxy it back to you. You can either write your own proxy or deploy a pre-built proxy.
Find some existing third party proxy service that you can use.
If you're interested in making your own node.js proxy, you can see a simple example here: How to create a simple http proxy in node.js?.

Execute route if only the local Angular App calls it true the controller

I have a few API routes that only the app itself (controller.js) should have access to. Is there a way to use an IP address (possibly insecure because of spoofing) to create a restriction of who uses this part of the api?
Server size (server.js)
app.get("/api/specs",function(req,res){
// Only the app should have access to it, not external entities
res.json({used:getUsed()});
});
Client side (controller.js)
$http.get('/api/specs').success(function(specs,code){
console.log(specs);
});
By default your browser doesn't allow you to make Cross-site HTTP requests because are subject of the same origin policy.
Note:
In particular, this meant that a web application using XMLHttpRequest
could only make HTTP requests to the domain it was loaded from, and
not to other domains.
Which it means in your case that only the js in the same domain of your api can have access to them.
What if I want to extend the use of the API to other domains?
Well in this case you have to setup in your backend api the Access-Control-Allow-Origin header.
Some eg:
// Cross-site HTTP requests from http://siteA.com
Access-Control-Allow-Origin: http://siteA.com
// Cross-site HTTP requests from all
Access-Control-Allow-Origin: *
If you want to debug this behaviour you can just open firebug and check in networks the headers of your requests.
References:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
I suppose that using a GET parameter is the easiest way.
Node.js(express)
app.get("/api/specs",function(req,res){
var queryParam = url.parse(req.url,true).query
if(queryParam.whois == "yourUniqueName"){
res.send("okay");
}else{
res.status(404);
res.send("NG");
}
});
angular
$http.get("/api/specs", {
params: { whois: "yourUniqueName" }
});
define names something unique for each APIs.
and set the server returns response only when a client sends correct name.
server returns 404 except you pass yourUniqueName as query parameter whois.
/api/specs?whois=yourUniqueName
okay
.
/api/specs?whois=otherName
/api/specs?otherParam=something
/api/specs
NG

Categories

Resources