Навчання
Mixed Content: Finding Insecure Resources on an HTTPS Page
Your page is HTTPS and something on it is not. Browsers block the dangerous half outright, which is why a mixed-content page often looks broken rather than insecure.
Запусти свіжий аудит DomainLens і використовуй звіт як список пріоритетів.
Active versus passive
Mixed content is any resource loaded over HTTP by a page served over HTTPS. Browsers split it in two, and the distinction decides whether you see a warning or a broken page.
Active content — scripts, stylesheets, iframes, XHR — can alter the page, so browsers block it outright. Passive content — images, video, audio — can only be displayed, so browsers load it and downgrade the security indicator. The blocked half is why a mixed-content page frequently appears unstyled or non-functional.
| Resource | Type | Browser behaviour |
|---|---|---|
| Script, stylesheet, iframe | Active | Blocked |
| XHR / fetch | Active | Blocked |
| Font | Active | Blocked |
| Image, video, audio | Passive | Loaded, padlock downgraded |
| Form action over HTTP | Active | Blocked or warned on submit |
What it costs
Directly, nothing in ranking terms — Google does not penalise mixed content. What it does is break the page: a blocked stylesheet means an unstyled render, a blocked script means missing content, and Googlebot sees the same broken version a visitor does.
For a client-rendered site the consequence is total. A blocked script means no content at all, so the page is indexed empty while looking fine in a browser that has cached the resource from elsewhere.
Finding every instance
- 1Open the browser console on an affected page — mixed content is reported explicitly there.
- 2Search the codebase and the database for http:// occurrences; CMS content fields are the usual hiding place.
- 3Check hardcoded absolute URLs in templates, which survive migrations that fix everything else.
- 4Look at third-party embeds and older ad or widget scripts, which are the most common external cause.
- 5Deploy a Content-Security-Policy report-only header to collect instances from real traffic rather than from your own browsing.
# In the codebase
grep -rn 'http://' --include='*.php' --include='*.js' \
--include='*.css' --include='*.html' .
# In served HTML
curl -s https://example.com/page \
| grep -oE '(src|href|action)="http://[^"]+' | sort -u
# In a database, for content stored as HTML
# SELECT id FROM posts WHERE body LIKE '%http://%';
Fixing it properly
The upgrade-insecure-requests directive tells browsers to try HTTPS for any HTTP resource. It is genuinely useful as a backstop and it hides the underlying problem, so the URLs stay wrong and break the day the directive is removed.
- Change http:// to https:// where the resource supports it — most do now.
- Use protocol-relative URLs only as a stopgap; they are legacy and an absolute https:// is clearer.
- Replace third-party resources that still have no HTTPS version. There is no fix that keeps them.
- Update stored content in the database, not just templates, or the problem returns with every old post.
- Add upgrade-insecure-requests to your CSP as a safety net, never as the fix.
Preventing recurrence
Store relative URLs for internal resources so they inherit the page's scheme automatically. For anything external, an absolute https:// URL and a check when the integration is added. Keep a report-only CSP running afterwards, since it will catch the next occurrence before a visitor does. See security headers for the header itself and the SSL checker for the certificate side of HTTPS.
How DomainLens contributes
DomainLens flags insecure resources on the pages it audits alongside the HTTPS check, so a page that looks secure in your browser but loads an HTTP script surfaces during a normal audit. For what happens when the certificate itself fails see SSL certificate expired .
- Does mixed content hurt SEO?
- Not as a ranking penalty. It breaks the page — blocked scripts and stylesheets mean Googlebot sees a broken render, and that does affect what gets indexed.
- Why is my padlock missing on an HTTPS page?
- Passive mixed content — usually an image loaded over HTTP. The browser loads it and downgrades the indicator rather than blocking it.
- Are protocol-relative URLs a good fix?
- They work and they are legacy. Now that HTTPS is universal, an explicit https:// is clearer and avoids surprises when a page is served over HTTP somewhere.
- Does upgrade-insecure-requests solve the problem?
- It masks it. Browsers will try HTTPS for those resources, but the URLs remain wrong and break as soon as the directive is removed.