search
Javascript star Featured

How to Fix Mixed Content Error: Complete Guide for HTTPS Websites

Learn how to fix mixed content errors on HTTPS websites. Complete guide with solutions for HTTP resources, images, scripts, and secure content loading.

person By Gautam Sharma
calendar_today January 8, 2026
schedule 15 min read
HTTPS SSL Mixed Content Security Web Development Error Handling

The ‘Mixed Content Error’ is a common security issue that occurs when a website served over HTTPS loads resources (such as images, scripts, stylesheets, or iframes) over HTTP. This creates a security vulnerability because the insecure resources can be intercepted or modified by attackers, compromising the security of the entire page.

This comprehensive guide provides complete solutions to resolve the mixed content error with practical examples and security best practices.


Understanding Mixed Content Errors

Mixed content occurs when a secure HTTPS page loads resources over an insecure HTTP connection. Modern browsers block these insecure resources to protect users, displaying warnings or preventing the resources from loading.

Types of Mixed Content:

  • Active Mixed Content: Scripts, plugins, iframes that can modify the page
  • Passive Mixed Content: Images, videos, audio that can’t modify the page

Common Error Messages:

  • Mixed Content: The page was loaded over HTTPS, but requested an insecure resource
  • Blocked loading mixed active content
  • Mixed Content blocked or Mixed Content warning
  • The page was loaded over HTTPS, but requested an insecure stylesheet

Common Causes and Solutions

1. Insecure Image Sources

The most common cause is loading images over HTTP on HTTPS pages.

❌ Problem Scenario:

<!-- ❌ This will cause mixed content error -->
<img src="http://example.com/image.jpg" alt="Example Image">
<img src="http://cdn.example.com/photo.png" alt="Photo">

✅ Solution: Use HTTPS for All Resources

<!-- ✅ Use HTTPS for all resources -->
<img src="https://example.com/image.jpg" alt="Example Image">
<img src="https://cdn.example.com/photo.png" alt="Photo">

<!-- ✅ Or use protocol-relative URLs -->
<img src="//example.com/image.jpg" alt="Example Image">

Loading scripts or CSS files over HTTP on HTTPS pages.

❌ Problem Scenario:

<!-- ❌ This will cause mixed content error -->
<link rel="stylesheet" href="http://example.com/styles.css">
<script src="http://example.com/script.js"></script>

✅ Solution: Secure Resource Loading

<!-- ✅ Use HTTPS for all resources -->
<link rel="stylesheet" href="https://example.com/styles.css">
<script src="https://example.com/script.js"></script>

<!-- ✅ Or use CDN with HTTPS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>

Solution 1: Protocol-Agnostic URLs

Use protocol-relative URLs to automatically match the page protocol.

Protocol-Relative URLs:

<!-- ✅ Protocol-relative URLs (automatically use HTTPS when page is HTTPS) -->
<img src="//example.com/image.jpg" alt="Example Image">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<script src="//code.jquery.com/jquery-3.6.0.min.js"></script>

<!-- ✅ For API calls -->
<script>
  // ✅ Use protocol-relative URLs for API calls
  fetch('//api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data));
</script>

JavaScript Protocol Handling:

// ✅ Dynamic protocol handling
function getSecureUrl(baseUrl) {
  if (window.location.protocol === 'https:') {
    return baseUrl.replace('http://', 'https://');
  }
  return baseUrl;
}

// ✅ Use current protocol
function getCurrentProtocolUrl(path) {
  const protocol = window.location.protocol;
  const hostname = window.location.hostname;
  const port = window.location.port ? ':' + window.location.port : '';
  return `${protocol}//${hostname}${port}${path}`;
}

// Usage
const imageUrl = getSecureUrl('http://example.com/image.jpg');
const apiUrl = getCurrentProtocolUrl('/api/data');

Solution 2: Content Security Policy (CSP)

Implement Content Security Policy to control resource loading.

CSP Headers:

// ✅ Server-side CSP configuration
app.use((req, res, next) => {
  // ✅ Block mixed content
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'", // Only allow resources from same origin
    "script-src 'self' 'unsafe-inline' https://cdn.example.com", // Allow HTTPS scripts
    "style-src 'self' 'unsafe-inline' https://cdn.example.com", // Allow HTTPS styles
    "img-src 'self' data: https:", // Allow HTTPS images and data URLs
    "font-src 'self' https://fonts.gstatic.com", // Allow HTTPS fonts
    "connect-src 'self' https://api.example.com", // Allow HTTPS API calls
    "frame-src https:", // Allow HTTPS iframes only
    "upgrade-insecure-requests" // Automatically upgrade HTTP requests to HTTPS
  ].join('; '));
  
  next();
});

Meta Tag CSP:

<!-- ✅ CSP meta tag for mixed content protection -->
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               script-src 'self' https://cdn.example.com; 
               style-src 'self' https://cdn.example.com; 
               img-src 'self' data: https:; 
               upgrade-insecure-requests;">

Solution 3: Automated URL Conversion

Create utilities to automatically convert HTTP URLs to HTTPS.

URL Conversion Utilities:

// ✅ URL conversion utilities
class UrlConverter {
  static toHttps(url) {
    if (!url) return url;
    
    // ✅ Convert HTTP to HTTPS
    if (url.startsWith('http://')) {
      return url.replace('http://', 'https://');
    }
    
    // ✅ Handle protocol-relative URLs
    if (url.startsWith('//')) {
      return `https:${url}`;
    }
    
    return url;
  }

  static convertHtml(html) {
    // ✅ Convert all HTTP URLs in HTML to HTTPS
    return html
      .replace(/http:\/\/([^"'\s]+)/g, 'https://$1')
      .replace(/src="(http:\/\/[^"']+)"/g, 'src="$1"')
      .replace(/href="(http:\/\/[^"']+)"/g, 'href="$1"');
  }

  static convertAttributes(element) {
    // ✅ Convert attributes in DOM element
    const httpAttrs = ['src', 'href', 'action', 'data'];
    
    httpAttrs.forEach(attr => {
      const value = element.getAttribute(attr);
      if (value && value.startsWith('http://')) {
        element.setAttribute(attr, this.toHttps(value));
      }
    });
  }

  static convertResourceUrls(resources) {
    // ✅ Convert array of resource URLs
    return resources.map(resource => {
      if (typeof resource === 'string') {
        return this.toHttps(resource);
      } else if (resource.url) {
        return { ...resource, url: this.toHttps(resource.url) };
      }
      return resource;
    });
  }
}

// Usage
const secureImageUrl = UrlConverter.toHttps('http://example.com/image.jpg');
const secureResources = UrlConverter.convertResourceUrls([
  'http://example.com/script.js',
  { url: 'http://example.com/style.css', type: 'css' }
]);

Automatic Conversion Middleware:

// ✅ Server-side middleware for URL conversion
function secureUrlMiddleware(req, res, next) {
  const originalSend = res.send;
  
  res.send = function(body) {
    if (typeof body === 'string' && req.secure) {
      // ✅ Convert HTTP URLs to HTTPS in HTML responses
      body = UrlConverter.convertHtml(body);
    }
    return originalSend.call(this, body);
  };
  
  next();
}

// ✅ Apply middleware
app.use(secureUrlMiddleware);

Solution 4: Asset Management for HTTPS

Properly manage assets to ensure they’re served over HTTPS.

Asset Management:

// ✅ Asset management for HTTPS
class AssetManager {
  constructor(baseUrl) {
    this.baseUrl = this.ensureHttps(baseUrl);
  }

  ensureHttps(url) {
    if (!url) return url;
    
    if (url.startsWith('http://')) {
      return url.replace('http://', 'https://');
    }
    
    if (url.startsWith('//')) {
      return `https:${url}`;
    }
    
    return url;
  }

  getImageUrl(path) {
    return `${this.baseUrl}/images/${path}`;
  }

  getScriptUrl(path) {
    return `${this.baseUrl}/js/${path}`;
  }

  getStyleUrl(path) {
    return `${this.baseUrl}/css/${path}`;
  }

  getAllAssets() {
    return {
      images: this.getAllImageUrls(),
      scripts: this.getAllScriptUrls(),
      styles: this.getAllStyleUrls()
    };
  }

  getAllImageUrls() {
    // ✅ Return all image URLs with HTTPS
    const images = [
      'logo.png',
      'banner.jpg',
      'icon.svg'
    ];
    
    return images.map(img => this.getImageUrl(img));
  }

  getAllScriptUrls() {
    // ✅ Return all script URLs with HTTPS
    const scripts = [
      'app.js',
      'vendor.js',
      'analytics.js'
    ];
    
    return scripts.map(script => this.getScriptUrl(script));
  }

  getAllStyleUrls() {
    // ✅ Return all style URLs with HTTPS
    const styles = [
      'main.css',
      'responsive.css',
      'theme.css'
    ];
    
    return styles.map(style => this.getStyleUrl(style));
  }
}

// Usage
const assetManager = new AssetManager('https://example.com');
const secureAssets = assetManager.getAllAssets();

React Component with Secure Assets:

// ✅ React component with secure asset loading
import React, { useState, useEffect } from 'react';

function SecureAssetComponent() {
  const [assets, setAssets] = useState({
    images: [],
    scripts: [],
    styles: []
  });

  useEffect(() => {
    const assetManager = new AssetManager('https://example.com');
    const secureAssets = assetManager.getAllAssets();
    setAssets(secureAssets);
  }, []);

  return (
    <div>
      {/* ✅ Secure image loading */}
      {assets.images.map((img, index) => (
        <img key={index} src={img} alt={`Image ${index}`} />
      ))}
      
      {/* ✅ Secure script loading */}
      {assets.scripts.map((script, index) => (
        <script key={index} src={script}></script>
      ))}
      
      {/* ✅ Secure style loading */}
      {assets.styles.map((style, index) => (
        <link key={index} rel="stylesheet" href={style} />
      ))}
    </div>
  );
}

Solution 5: API and External Resource Handling

Handle API calls and external resources securely.

Secure API Calls:

// ✅ Secure API client
class SecureApiClient {
  constructor(baseApiUrl) {
    this.baseApiUrl = this.ensureHttps(baseApiUrl);
  }

  ensureHttps(url) {
    if (!url) return url;
    
    if (url.startsWith('http://')) {
      return url.replace('http://', 'https://');
    }
    
    if (url.startsWith('//')) {
      return `https:${url}`;
    }
    
    return url;
  }

  async get(endpoint, options = {}) {
    const url = `${this.baseApiUrl}${endpoint}`;
    
    try {
      const response = await fetch(url, {
        ...options,
        headers: {
          'Content-Type': 'application/json',
          ...options.headers
        }
      });
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      
      return await response.json();
    } catch (error) {
      console.error('API call failed:', error);
      throw error;
    }
  }

  async post(endpoint, data, options = {}) {
    return this.get(endpoint, {
      method: 'POST',
      body: JSON.stringify(data),
      ...options
    });
  }

  // ✅ Handle mixed content in API responses
  async getSecureData(endpoint) {
    const data = await this.get(endpoint);
    
    // ✅ Convert any HTTP URLs in response to HTTPS
    return this.convertHttpUrlsToHttps(data);
  }

  convertHttpUrlsToHttps(obj) {
    if (typeof obj !== 'object' || obj === null) {
      return obj;
    }

    if (Array.isArray(obj)) {
      return obj.map(item => this.convertHttpUrlsToHttps(item));
    }

    const converted = {};
    for (const [key, value] of Object.entries(obj)) {
      if (typeof value === 'string' && value.startsWith('http://')) {
        converted[key] = value.replace('http://', 'https://');
      } else if (typeof value === 'object' && value !== null) {
        converted[key] = this.convertHttpUrlsToHttps(value);
      } else {
        converted[key] = value;
      }
    }

    return converted;
  }
}

// Usage
const apiClient = new SecureApiClient('https://api.example.com');

Solution 6: Upgrade Insecure Requests

Use the upgrade-insecure-requests directive to automatically upgrade HTTP requests.

Upgrade Insecure Requests:

// ✅ Check if upgrade-insecure-requests is supported
function supportsUpgradeInsecureRequests() {
  try {
    // ✅ Check if CSP upgrade-insecure-requests is supported
    const csp = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
    if (csp) {
      return csp.content.includes('upgrade-insecure-requests');
    }
  } catch (error) {
    // CSP not supported
  }
  return false;
}

// ✅ Manual upgrade function
function upgradeInsecureRequests() {
  // ✅ Upgrade all HTTP resources to HTTPS
  const elements = document.querySelectorAll('[src], [href], [action], [data]');
  
  elements.forEach(element => {
    const attrs = ['src', 'href', 'action', 'data'];
    
    attrs.forEach(attr => {
      const value = element.getAttribute(attr);
      if (value && value.startsWith('http://')) {
        const secureValue = value.replace('http://', 'https://');
        element.setAttribute(attr, secureValue);
      }
    });
  });
}

// ✅ Run on page load
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', upgradeInsecureRequests);
} else {
  upgradeInsecureRequests();
}

Server-Side Implementation:

// ✅ Server-side upgrade insecure requests
app.use((req, res, next) => {
  if (req.secure || req.headers['x-forwarded-proto'] === 'https') {
    // ✅ Add upgrade-insecure-requests header
    res.setHeader('Content-Security-Policy', 'upgrade-insecure-requests');
  }
  next();
});

Solution 7: Content Delivery Network (CDN) Configuration

Configure CDNs to serve content over HTTPS.

CDN Configuration:

// ✅ CDN configuration for HTTPS
class CdnManager {
  constructor(cdnUrl) {
    this.cdnUrl = this.ensureHttps(cdnUrl);
  }

  ensureHttps(url) {
    if (!url) return url;
    
    if (url.startsWith('http://')) {
      return url.replace('http://', 'https://');
    }
    
    if (url.startsWith('//')) {
      return `https:${url}`;
    }
    
    return url;
  }

  getImagePath(imageName) {
    return `${this.cdnUrl}/images/${imageName}`;
  }

  getVideoPath(videoName) {
    return `${this.cdnUrl}/videos/${videoName}`;
  }

  getAudioPath(audioName) {
    return `${this.cdnUrl}/audio/${audioName}`;
  }

  getFontPath(fontName) {
    return `${this.cdnUrl}/fonts/${fontName}`;
  }

  // ✅ Generate secure URLs for all assets
  getAllAssetUrls() {
    return {
      images: [
        this.getImagePath('logo.png'),
        this.getImagePath('banner.jpg')
      ],
      videos: [
        this.getVideoPath('intro.mp4'),
        this.getVideoPath('tutorial.webm')
      ],
      fonts: [
        this.getFontPath('main-font.woff2'),
        this.getFontPath('icons.woff2')
      ]
    };
  }
}

// Usage
const cdnManager = new CdnManager('https://cdn.example.com');
const secureAssets = cdnManager.getAllAssetUrls();

Solution 8: Testing and Validation

Test your website for mixed content issues.

Mixed Content Testing:

// ✅ Mixed content detection
class MixedContentDetector {
  static findInsecureResources() {
    const insecureElements = [];
    
    // ✅ Find all HTTP resources
    const elements = document.querySelectorAll('[src], [href], [action], [data]');
    
    elements.forEach(element => {
      const attrs = ['src', 'href', 'action', 'data'];
      
      attrs.forEach(attr => {
        const value = element.getAttribute(attr);
        if (value && value.startsWith('http://')) {
          insecureElements.push({
            element: element.tagName,
            attribute: attr,
            url: value,
            selector: this.getElementSelector(element)
          });
        }
      });
    });
    
    return insecureElements;
  }

  static getElementSelector(element) {
    // ✅ Generate CSS selector for element
    if (element.id) {
      return `#${element.id}`;
    }
    
    if (element.className) {
      return `${element.tagName.toLowerCase()}.${element.className.split(' ')[0]}`;
    }
    
    return element.tagName.toLowerCase();
  }

  static async validatePage() {
    const insecureResources = this.findInsecureResources();
    
    if (insecureResources.length > 0) {
      console.warn('Mixed content detected:', insecureResources);
      
      // ✅ Report to external service
      await this.reportMixedContent(insecureResources);
      
      return {
        hasMixedContent: true,
        insecureResources,
        count: insecureResources.length
      };
    }
    
    return {
      hasMixedContent: false,
      insecureResources: [],
      count: 0
    };
  }

  static async reportMixedContent(resources) {
    // ✅ Send mixed content report to external service
    try {
      await fetch('/api/mixed-content-report', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          pageUrl: window.location.href,
          resources,
          timestamp: new Date().toISOString()
        })
      });
    } catch (error) {
      console.error('Failed to report mixed content:', error);
    }
  }
}

// ✅ Run validation
MixedContentDetector.validatePage().then(result => {
  if (result.hasMixedContent) {
    console.log(`Found ${result.count} insecure resources`);
    // Handle mixed content
  }
});

Automated Testing:

// ✅ Automated mixed content test
function testMixedContent() {
  const tests = {
    images: document.querySelectorAll('img[src^="http://"]'),
    scripts: document.querySelectorAll('script[src^="http://"]'),
    styles: document.querySelectorAll('link[rel="stylesheet"][href^="http://"]'),
    iframes: document.querySelectorAll('iframe[src^="http://"]'),
    forms: document.querySelectorAll('form[action^="http://"]')
  };

  const results = {};
  let totalIssues = 0;

  for (const [type, elements] of Object.entries(tests)) {
    results[type] = {
      count: elements.length,
      elements: Array.from(elements).map(el => ({
        tagName: el.tagName,
        src: el.src || el.href || el.action,
        outerHTML: el.outerHTML.substring(0, 100) + '...'
      }))
    };
    totalIssues += elements.length;
  }

  return {
    totalIssues,
    results,
    isSecure: totalIssues === 0
  };
}

// ✅ Run automated test
const testResults = testMixedContent();
console.log('Mixed Content Test Results:', testResults);

Solution 9: Performance Optimization

Optimize for performance while maintaining security.

Optimized Secure Loading:

// ✅ Optimized secure resource loading
class OptimizedSecureLoader {
  static async loadResource(url, type = 'script') {
    return new Promise((resolve, reject) => {
      // ✅ Ensure HTTPS
      const secureUrl = url.startsWith('http://') 
        ? url.replace('http://', 'https://') 
        : url;

      let element;
      
      switch (type) {
        case 'script':
          element = document.createElement('script');
          element.src = secureUrl;
          element.async = true;
          break;
          
        case 'style':
          element = document.createElement('link');
          element.rel = 'stylesheet';
          element.href = secureUrl;
          break;
          
        case 'image':
          element = document.createElement('img');
          element.src = secureUrl;
          break;
          
        default:
          reject(new Error('Unsupported resource type'));
          return;
      }

      element.onload = () => resolve(element);
      element.onerror = () => reject(new Error(`Failed to load ${type}: ${secureUrl}`));

      document.head.appendChild(element);
    });
  }

  static async loadMultipleResources(resources) {
    // ✅ Load multiple resources with error handling
    const promises = resources.map(resource => 
      this.loadResource(resource.url, resource.type)
        .catch(error => {
          console.error(`Failed to load ${resource.type}:`, error);
          return null;
        })
    );

    return Promise.all(promises);
  }

  static preloadSecureResources(urls) {
    // ✅ Preload secure resources
    urls.forEach(url => {
      const link = document.createElement('link');
      link.rel = 'preload';
      link.as = 'script'; // or 'style', 'image', etc.
      link.href = url.startsWith('http://') 
        ? url.replace('http://', 'https://') 
        : url;
      
      document.head.appendChild(link);
    });
  }
}

// Usage
OptimizedSecureLoader.loadResource('https://example.com/script.js', 'script')
  .then(script => console.log('Script loaded:', script))
  .catch(error => console.error('Script load failed:', error));

Performance Considerations

Secure Performance Optimization:

// ✅ Performance-optimized secure loading
class SecurePerformanceOptimizer {
  constructor() {
    this.loadedResources = new Set();
  }

  async loadSecureResource(url, options = {}) {
    // ✅ Ensure HTTPS
    const secureUrl = this.ensureHttps(url);
    
    // ✅ Avoid duplicate loads
    if (this.loadedResources.has(secureUrl)) {
      return Promise.resolve();
    }

    try {
      const response = await fetch(secureUrl, {
        method: 'HEAD', // Only check if resource exists
        cache: 'force-cache'
      });

      if (!response.ok) {
        throw new Error(`Resource not available: ${secureUrl}`);
      }

      // ✅ Actually load the resource
      const element = document.createElement('link');
      element.rel = 'preload';
      element.as = options.as || 'script';
      element.href = secureUrl;

      document.head.appendChild(element);

      this.loadedResources.add(secureUrl);
      return element;
    } catch (error) {
      console.error('Secure resource load failed:', error);
      throw error;
    }
  }

  ensureHttps(url) {
    if (!url) return url;
    
    if (url.startsWith('http://')) {
      return url.replace('http://', 'https://');
    }
    
    if (url.startsWith('//')) {
      return `https:${url}`;
    }
    
    return url;
  }
}

Security Considerations

Secure Mixed Content Handling:

// ✅ Secure mixed content handling
class SecureMixedContentHandler {
  static validateResourceUrl(url) {
    // ✅ Validate URL format
    try {
      const parsedUrl = new URL(url);
      
      // ✅ Only allow HTTPS for external resources
      if (parsedUrl.protocol !== 'https:' && parsedUrl.hostname !== window.location.hostname) {
        throw new Error(`External resources must use HTTPS: ${url}`);
      }
      
      // ✅ Validate domain
      const allowedDomains = [
        window.location.hostname,
        'cdn.example.com',
        'api.example.com'
      ];
      
      if (!allowedDomains.includes(parsedUrl.hostname)) {
        throw new Error(`Domain not allowed: ${parsedUrl.hostname}`);
      }
      
      return true;
    } catch (error) {
      console.error('Invalid resource URL:', error);
      return false;
    }
  }

  static async secureFetch(url, options = {}) {
    // ✅ Ensure URL is secure before fetching
    const secureUrl = url.startsWith('http://') 
      ? url.replace('http://', 'https://') 
      : url;

    if (!this.validateResourceUrl(secureUrl)) {
      throw new Error('Invalid resource URL');
    }

    return fetch(secureUrl, options);
  }

  static createSecureIframe(src, options = {}) {
    // ✅ Create secure iframe
    const secureSrc = src.startsWith('http://') 
      ? src.replace('http://', 'https://') 
      : src;

    if (!this.validateResourceUrl(secureSrc)) {
      throw new Error('Invalid iframe source');
    }

    const iframe = document.createElement('iframe');
    iframe.src = secureSrc;
    
    // ✅ Set security attributes
    iframe.sandbox = options.sandbox || 'allow-scripts allow-same-origin';
    iframe.allow = options.allow || 'encrypted-media; fullscreen';
    
    return iframe;
  }
}

Common Mistakes to Avoid

1. Loading External Resources Over HTTP:

// ❌ Don't do this
const externalScript = document.createElement('script');
externalScript.src = 'http://example.com/script.js'; // ❌ HTTP resource
document.head.appendChild(externalScript);

2. Forgetting to Update API Endpoints:

// ❌ Don't do this
const apiUrl = 'http://api.example.com'; // ❌ HTTP API
fetch(`${apiUrl}/data`); // Will fail in HTTPS context

3. Not Validating External Content:

// ❌ Don't do this
const userContent = '<img src="http://malicious.com/image.jpg">';
document.getElementById('content').innerHTML = userContent; // Security risk

Alternative Solutions

Using React DevTools for Mixed Content:

// Component with mixed content detection
function MixedContentDetector() {
  const [mixedContent, setMixedContent] = useState(null);

  useEffect(() => {
    const detector = new MixedContentDetector();
    detector.validatePage().then(setMixedContent);
  }, []);

  return (
    <div data-testid="mixed-content-detector">
      {mixedContent && (
        <div>
          <h3>Mixed Content Report</h3>
          <p>Issues found: {mixedContent.count}</p>
          <pre>{JSON.stringify(mixedContent.results, null, 2)}</pre>
        </div>
      )}
    </div>
  );
}

Feature Detection:

// Check for mixed content support
function checkMixedContentSupport() {
  const hasCSP = typeof document !== 'undefined' && 
                document.querySelector('meta[http-equiv="Content-Security-Policy"]');
  
  const hasSecureContext = typeof window !== 'undefined' && 
                          window.isSecureContext;
  
  return {
    hasCSP,
    hasSecureContext,
    supportsUpgradeInsecureRequests: hasCSP && 
      document.querySelector('meta[http-equiv="Content-Security-Policy"]').content.includes('upgrade-insecure-requests')
  };
}

Troubleshooting Checklist

When encountering mixed content errors:

  1. Check Browser Console: Look for specific mixed content warnings
  2. Verify All Resources: Ensure all images, scripts, stylesheets use HTTPS
  3. Test API Calls: Confirm all API endpoints use HTTPS
  4. Review External Content: Check iframes, embedded content use HTTPS
  5. Validate CSP Headers: Ensure Content Security Policy is properly configured
  6. Test in Different Browsers: Verify behavior across browsers
  7. Use Developer Tools: Inspect network requests for HTTP resources

Conclusion

The ‘Mixed Content Error’ occurs when HTTPS pages load insecure HTTP resources, creating security vulnerabilities. By implementing proper HTTPS protocols, Content Security Policies, and secure resource loading techniques, you can resolve these errors and ensure your website remains secure and functional.

The key to resolving mixed content errors is ensuring all resources are loaded over HTTPS, implementing proper security policies, and thoroughly testing your website across different environments. Whether you’re working with images, scripts, APIs, or external content, the solutions provided in this guide will help you maintain a secure, HTTPS-compliant website.

Remember to always validate your resource URLs, implement proper error handling, and use Content Security Policies to prevent mixed content issues in your web applications.

Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

Javascript

How to Fix setTimeout Undefined Issue in JavaScript: Expert Solutions

Discover how to resolve the common setTimeout undefined error in JavaScript. Learn practical fixes for browser and Node.js environments with detailed examples and troubleshooting tips.

January 2, 2026
Tutorials

Fix: HTTPS required but site loading HTTP - Mixed Content Error Guide

Complete guide to fix mixed content errors when HTTPS is required but site loads HTTP resources. Learn how to resolve HTTP to HTTPS issues with practical solutions for React, Angular, and Vue applications.

January 8, 2026
Javascript

Build PDFs Directly in the Browser: jsPDF vs pdf-lib vs PDF.js (Real Examples & Use Cases)

A practical comparison of jsPDF, pdf-lib, and PDF.js for browser-based PDF generation and manipulation. Learn which library fits your project with real code examples.

December 31, 2024