"Mixed Content Blocked" When Running an Http Ajax Operation in an Https Page

Mixed content blocked when running an HTTP AJAX operation in an HTTPS page

If you load a page in your browser using HTTPS, the browser will refuse to load any resources over HTTP. As you've tried, changing the API URL to have HTTPS instead of HTTP typically resolves this issue. However, your API must not allow for HTTPS connections. Because of this, you must either force HTTP on the main page or request that they allow HTTPS connections.

Note on this: The request will still work if you go to the API URL instead of attempting to load it with AJAX. This is because the browser is not loading a resource from within a secured page, instead it's loading an insecure page and it's accepting that. In order for it to be available through AJAX, though, the protocols should match.

Mixed content jQuery ajax HTTPS request has been blocked on Laravel

Summary:
I needed to replace var relUrl = '/fb/json/'; with var relUrl = '/fb/json'; (remove the trailing slash) because that's what my Laravel web.php routes file expected.


In Chrome console, I noticed that the https XHR request was being "canceled" and replaced with an http request.

So then I used ssh to log into the remote production server and vim to temporarily disable the requirement of authentication.

Then in the Chrome console, I defined and ran a new ajax command using an absolute https URL with querystring params on the end. That worked (no mixed content error). Then I tried a relative URL like that, and it worked too.

Even a relative URL with no payload or querystring params or trailing slash worked.

Then I added the trailing slash again, and it didn't work.

I still wish there had been an easier way to trace or debug the redirect paths or whatever was happening. I still feel like I stumbled onto the answer clumsily (after many hours) instead of knowing how to dissect this problem reliably.

error: Mixed Content: The page at ____' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint This request has been blocked

This means that you accessed your website using HTTPS, but when you XMLHttpRequest, you're using HTTP in that code. It would be helpful to see that code. If you're using XMLHttpRequest like this: http://example.com/, change it to: https://example.com/. This error means you need to use all HTTPS or all HTTP.

Edit: According to another StackOverflow post, you should actually leave out the http/https completely:
//example.com/

How to stop Mixed Content error when making an AJAX request via Varnish/Nginx

Seems like the base URL needs changing.

Looking at the error message above, the address it's complaining about is http://website.co.uk/blog/expertise//ajax/.... The double slash looks like a concat somewhere, so my guess is it's concatenating your relative /ajax/... path onto the base URL http://website.co.uk/blog/expertise/. If you can find where it's getting that base URL from, change it to use HTTPS, and probably remove the trailing slash, like https://website.co.uk/blog/expertise.

Base URLs are often defined in settings of site builders so the site knows how to construct revisit or redirection URLs. Often sites are behind proxies, and SSL is usually terminated way before they see the request, so it is not obvious what the external URL really looked like without pre-configuring the static part of it.

Mixed-content request from HTTPS page to HTTP (non-HTTPS) localhost address not blocked

http://127.0.100.2/img.jpg isn’t considered mixed content because the Mixed Content spec defines it as a special case of an a priori authenticated URL, due to it being in the range 127.0.0.0 - 127.255.255.255 (that is, a host with the CIDR notation 127.0.0.0/8), which per the Secure Contexts spec is defined as a secure context — even if the protocol isn’t https.

The same goes for http://localhost/img.jpg or http://foo.localhost/img.jpg

does mixed content error mentioning script mean that the problem comes from an HTML script tag?

TL;DR

The word "script" in the message means that the specific non-https resource that was blocked from loading in this case was of type "script". Why exactly that non-https resource request was generated in the first place is not covered in the error message...

Most browsers will block http resources from loading on https sites now.
Best practice is https for everything (main site and all things loaded by that site).

To track down where that http call is coming from...

  • open your browser dev tools
  • clear cookies
  • go to "network" tab and disable cache
  • refresh page and look for the blocked request
  • the network panel will usually show an "initiator" column that tells you which script/file initiated the call. Might be index.html, might be some other script. If you don't see the column it might be hidden and right clicking on the column headings area may allow you to choose which columns are shown.

More details

Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure_____ 'http://...'. This request has been blocked; the content must be served over HTTPS.

Browsers (not just chrome) have been doing this for a while as a security feature.

Imagine that your eCommerce website https://www.example.com is served securely. However you load a javascript file from http://www.example.com/site.js insecurely. Because that site.js was served insecurely, it could easily be modified by a Man in the Middle (MITM) to do things like steal credit card numbers from the customers of your shop during checkout.

Even passive ("display") content like images has issues when serving insecurely. As an example...A man-in-the-middle could rewrite the image response to redirect to another URL on another domain that enables them to set cookies on your users in order to later serve your customers ads for your competitor. Or just changing the images on your site to display something else.

In general the web has moved to https only for all sites. The availability of free, auto-renewing, domain-validation certificates from LetsEncrypt has made this relatively trouble-free.

Server Name Indication (SNI) TLS extension support (all major OSes after Windows XP) also means that https works properly even when different domains are served from the same IP address (cheap/budget shared hosting). So really no excuses not to do https by default.

Current best practices (just the basics...lot more you can do):

  • redirect all http to https for your domain(s)
  • utilize certbot to automate receiving domain-validated certs for your domain from LetsEncrypt. All modern web-hosting companies should be handling this automatically for you. If you run/manage your own server then you need to setup certbot yourself.
  • all resources (stylesheets, scripts, images, fonts) loaded by your site should be https. If you use a CDN on a different subdomain, that should also be secured.
  • use http-only, secure cookies.
  • use content security policy to lock down which domains/resources are allowed on your site (prevent hacked third-party resources from easily exfiltrating your users' data via calls to unauthorized domains).
  • lots more you can do if you are handling sensitive data...

Some example scenarios...

  • initiator: index.html - the reference to that script is in the actual html file.
  • initiator: site.js - the initiator is in one of your site's javascript files or the configuration for a react/vue/angular/etc javascript app
  • initiator: gtm.js - the initiator is inside google tag manager. check your pixels in the google tag manager interface...most likely will be a custom html pixel needs to be updated from http to https.
  • initiator: site.css - might be you have a font or image url in your css file that needs to be updated from http to https.
  • initiator: some-plugin.js - some wordpress plugin or other javascript-based widget you have added to your site is generating an insecure request.

References

  • Mixed content (MDN)
  • LetsEncrypt
  • certbot (github)
  • Server Name Indication

Page loaded over HTTPS but requested an insecure XMLHttpRequest endpoint

What I can do to fix this (other than installing a real SSL certificate).

You can't.

On an https webpage you can only make AJAX request to https webpage (With a certificate trusted by the browser, if you use a self-signed one, it will not work for your visitors)

AJAX calls to fail with mixed content HTTP/HTTPS errors, can't force HTTPS

I found a solution and now posting an answer to my own question. Don't ask me how I figured this out because I won't be able to give you a definite answer but this is what did it:

$url = "/myapi/get_company?code=" + e;

changed to:

$url = "/myapi/get_company/?code=" + e;

Notice the trailing slash, right before the parameters. The actual file handling the AJAX calls on the server side is here:

/myapi/get_company/index.php


Related Topics



Leave a reply



Submit