I am having a site with some pages on HTTPS connection. From these HTTPS pages, I have to use a HTTP Ajax request for some errors retrieval like blank fields. But this error messages are not coming. Is there any solution to it or I have to make that AJAX request to file on HTTPS connection?
-
ajax should run fine on https, can you post your actual code snippet? – Manny Oct 27 '10 at 10:19
-
2Sounds like SOP (http://en.wikipedia.org/wiki/Same_origin_policy): the schemas are different, so it is a different origin. – Colin Fine Oct 27 '10 at 10:19
-
Thanks for the answer. I have changed my website accordingly. – cooldude Oct 27 '10 at 18:51
8 Answers
This is not possible due to the Same Origin Policy.
You will need to switch the Ajax requests to https, too.

- 2,051
- 1
- 23
- 32

- 442,112
- 142
- 972
- 1,088
-
2Even the working draft of Cross-Origin Resource Sharing makes it impossible: http://www.w3.org/TR/cors/#user-agent-security – Harmen Oct 27 '10 at 10:26
-
Thanks for the answer everyone. I have changed my website according to same origin policy. – cooldude Oct 27 '10 at 18:51
-
2@NickSotiros Why would you not want it secure? There's zero downside, and HTTP requests on an HTTPS page could potentially be attacked by a MITM to inject malicious JS. – ceejayoz May 19 '15 at 18:32
-
2@ceejayoz Well if you download a js script and execute it you could be attacked by a MITM. But if you just want to use someone else's background image in your css or download a youtube video, you can't. Why does the browser assume that content loaded via an ajax request is going to be javascript to execute? There is the site https://prezi.com which allows you to generate online presentations with online content pulled in from external resources, they must be using proxies. – Nick Sotiros May 20 '15 at 23:18
-
2@NickSotiros actually someones css can hook to inputs and send all data entered in those inputs to a bad server. – Olga Nov 24 '15 at 15:46
-
i have the same problem but this time my http domain is in the local domain not public,so https blocked by browser because ssl not verified,what can i do in this case – user818117 Jun 01 '18 at 12:24
-
1@user818117 I don't know whther it's suitable for bridging https and non-https requests, but theoretically, having your local server emit a CORS header: `Access-Control-Allow-Origin: http://yourlocal.resource`. See "The Cross-Origin Resource Sharing method" in the top answer to this: https://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy – Pekka Jun 01 '18 at 13:47
-
@Pekka웃 my local server emits Access-Control-Allow-Origin: *; the thing is from https i cant make request to http(so i cant use as ```http://yourlocal.resource```),if i make local server https as (```https://yourlocal.resource```) this time browser complains as same as in red address bar,and blocks json request – user818117 Jun 01 '18 at 14:45
-
1@user818117 ah. Then you'd have to get SSL actually running on your local server. Not sure how difficult it is but here's instructions https://stackoverflow.com/questions/3164629/how-to-set-up-https-for-local-testing-purposes – Pekka Jun 01 '18 at 14:55
Without any server side solution, Theres is only one way in which a secure page can get something from a insecure page/request and that's thought postMessage and a popup
I said popup cuz the site isn't allowed to mix content. But a popup isn't really mixing. It has it's own window but are still able to communicate with the opener with postMessage.
So you can open a new http-page with window.open(...)
and have that making the request for you
XDomain came to mind when i wrote this but here is a modern approach using the new fetch api, the advantage is the streaming of large files, the downside is that it won't work in all browser
You put this proxy script on any http page
onmessage = evt => {
const port = evt.ports[0]
fetch(...evt.data).then(res => {
// the response is not clonable
// so we make a new plain object
const obj = {
bodyUsed: false,
headers: [...res.headers],
ok: res.ok,
redirected: res.redurected,
status: res.status,
statusText: res.statusText,
type: res.type,
url: res.url
}
port.postMessage(obj)
// Pipe the request to the port (MessageChannel)
const reader = res.body.getReader()
const pump = () => reader.read()
.then(({value, done}) => done
? port.postMessage(done)
: (port.postMessage(value), pump())
)
// start the pipe
pump()
})
}
Then you open a popup window in your https page (note that you can only do this on a user interaction event or else it will be blocked)
window.popup = window.open(http://.../proxy.html)
create your utility function
function xfetch(...args) {
// tell the proxy to make the request
const ms = new MessageChannel
popup.postMessage(args, '*', [ms.port1])
// Resolves when the headers comes
return new Promise((rs, rj) => {
// First message will resolve the Response Object
ms.port2.onmessage = ({data}) => {
const stream = new ReadableStream({
start(controller) {
// Change the onmessage to pipe the remaning request
ms.port2.onmessage = evt => {
if (evt.data === true) // Done?
controller.close()
else // enqueue the buffer to the stream
controller.enqueue(evt.data)
}
}
})
// Construct a new response with the
// response headers and a stream
rs(new Response(stream, data))
}
})
}
And make the request like you normally do with the fetch api
xfetch('http://httpbin.org/get')
.then(res => res.text())
.then(console.log)

- 34,080
- 13
- 108
- 131
-
Nice, created a module [`cors-bypass`](https://www.npmjs.com/package/cors-bypass) that does this seamlessly. – Sam Denty Jan 06 '19 at 19:49
-
-
2@Chiwda no, because you are mixing secure with insecure content then, using a popup isn't mixing – Endless Sep 07 '19 at 11:16
-
I finally did this in a very simple way: w = window.open("",'_blank', 'toolbar=no,titlebar=no,status=no,menubar=no,scrollbars=no,resizable=no,left=12000, top=12000,width=10,height=10,visible=none', ''); w.location.href = MyURI; setTimeout(function() { w.close(); }, 6000) – Chiwda Sep 12 '19 at 15:21
Still, this can be done with the following steps:
send an https ajax request to your web-site (the same domain)
jQuery.ajax({ 'url' : '//same_domain.com/ajax_receiver.php', 'type' : 'get', 'data' : {'foo' : 'bar'}, 'success' : function(response) { console.log('Successful request'); } }).fail(function(xhr, err) { console.error('Request error'); });
get ajax request, for example, by php, and make a CURL get request to any desired website via http.
use linslin\yii2\curl; $curl = new curl\Curl(); $curl->get('http://example.com');

- 6,854
- 14
- 53
- 55

- 125
- 3
- 9
-
1This concept worked perfect (using code relevant to my setup/project). I created a php file on my server and did a curl request on an HTTP Url. I called this file from my HTTPS website and sent in the variable I needed for the API and voila! – Quasi635 Nov 02 '18 at 08:50
-
I only know may endpoint, how to use this method to my website. My website is https and API is `http://5ty.org:8080/api/card/post` – phuocding Jan 28 '19 at 02:49
-
The downside is if you have many concurrent requests to your page, then you could saturate your server. – Mirko Feb 04 '20 at 14:19
In some cases a one-way request without a response can be fired to a TCP server, without a SSL certificate. A TCP server, in contrast to a HTTP server, will catch you request. However there will be no access to any data sent from the browser, because the browser will not send any data without a positive certificate check. And in special cases even a bare TCP signal without any data is enough to execute some tasks. For example for an IoT device within a LAN to start a connection to an external service. Link
This is a kind of a "Wake Up" trigger, that works on a port without any security.
In case a response is needed, this can be implemented using a secured public https server, which can send the needed data back to the browser using e.g. Websockets.

- 718
- 6
- 7
Make a bypass API in server.js. This works for me.
app.post('/by-pass-api',function(req, response){
const url = req.body.url;
console.log("calling url", url);
request.get(
url,
(error, res, body) => {
if (error) {
console.error(error)
return response.status(200).json({'content': "error"})
}
return response.status(200).json(JSON.parse(body))
},
)
})
And call it using axios or fetch like this:
const options = {
method: 'POST',
headers: {'content-type': 'application/json'},
url:`http://localhost:3000/by-pass-api`, // your environment
data: { url }, // your https request here
};

- 3,752
- 35
- 31
- 35

- 21
- 1
I've created a module called cors-bypass
, that allows you to do this without the need for a server. It uses postMessage
to send cross-domain events, which is used to provide mock HTTP APIs (fetch
, WebSocket
, XMLHTTPRequest
etc.).
It fundamentally does the same as the answer by Endless, but requires no code changes to use it.
Example usage:
import { Client, WebSocket } from 'cors-bypass'
const client = new Client()
await client.openServerInNewTab({
serverUrl: 'http://random-domain.com/server.html',
adapterUrl: 'https://your-site.com/adapter.html'
})
const ws = new WebSocket('ws://echo.websocket.org')
ws.onopen = () => ws.send('hello')
ws.onmessage = ({ data }) => console.log('received', data)

- 3,693
- 3
- 30
- 43
This works for me. Make a bypass API in server.js or index.js. I am using express.js library.
import express from 'express';
import bodyParser from 'body-parser'; // custom_code
import axios from 'axios'; // custom-code
let app = express();
const jsonParser = bodyParser.json();
app.post('/by-pass-api', jsonParser, async (req, response) => {
const { url } = req.body;
const data = { data: req.body.data };
const result = await axios.post(url, data);
response.send({ success: true, result: result });
});
app.listen(3000, () => {
console.log(`Server is running as on port 3000`);
});
Create a function to call your localhost server(your application server) using axios or fetch like this:
url:
http://your-http-api-url
: This is external http url.
axios.post("http://localhost:3000/by-pass-api", {
headers: { "content-type": "application/json" },
url: `http://your-http-api-url`,
data: {...your_payload},
})

- 501
- 3
- 9
- 20
From the javascript I tried from several ways and I could not.
You need an server side solution, for example on c# I did create an controller that call to the http, en deserialize the object, and the result is that when I call from javascript, I'm doing an request from my https://domain to my htpps://domain. Please see my c# code:
[Authorize]
public class CurrencyServicesController : Controller
{
HttpClient client;
//GET: CurrencyServices/Consultar?url=valores?moedas=USD&alt=json
public async Task<dynamic> Consultar(string url)
{
client = new HttpClient();
client.BaseAddress = new Uri("http://api.promasters.net.br/cotacao/v1/");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
System.Net.Http.HttpResponseMessage response = client.GetAsync(url).Result;
var FromURL = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject(FromURL);
}
And let me show to you my client side (Javascript)
<script async>
$(document).ready(function (data) {
var TheUrl = '@Url.Action("Consultar", "CurrencyServices")?url=valores';
$.getJSON(TheUrl)
.done(function (data) {
$('#DolarQuotation').html(
'$ ' + data.valores.USD.valor.toFixed(2) + ','
);
$('#EuroQuotation').html(
'€ ' + data.valores.EUR.valor.toFixed(2) + ','
);
$('#ARGPesoQuotation').html(
'Ar$ ' + data.valores.ARS.valor.toFixed(2) + ''
);
});
});
I wish that this help you! Greetings

- 129
- 2
- 4