Fast and lightweight polyfill for min/max-width CSS3 Media Queries for IE 6-8 and more
—
The cross-domain proxy system enables respond.js to work with stylesheets hosted on CDNs or different domains by overcoming same-origin policy restrictions. This is essential for modern web applications that serve CSS from content delivery networks.
Three files must be properly configured for cross-domain functionality:
<!-- External domain: Proxy handler page -->
respond-proxy.html
<!-- Local domain: Redirect image for communication (1x1 transparent GIF) -->
respond.proxy.gif
<!-- Local domain: Proxy script -->
respond.proxy.jsFile Descriptions:
<!-- Respond.js proxy on external server (CDN) -->
<link href="http://externalcdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
<!-- Respond.js redirect location on local server -->
<link href="/path/to/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />
<!-- Respond.js proxy script on local server -->
<script src="/path/to/respond.proxy.js"></script>Enables respond.js to fetch and process CSS files from external domains that would normally be blocked by browser security policies.
/**
* Main proxy functions available via respond.proxy.js
*/
interface CrossDomainProxy {
/**
* Fetch CSS content from external domain via iframe proxy
* @param url - External CSS file URL to fetch
* @param callback - Function called with retrieved CSS content
*/
fakejax(url: string, callback: (css: string) => void): void;
/**
* Check if URL needs base URL resolution
* @param href - URL to check against base element
* @returns Resolved absolute URL
*/
checkBaseURL(href: string): string;
/**
* Build URLs list of external stylesheets for processing
* Scans all link elements and initiates proxy requests for external stylesheets
*/
buildUrls(): void;
/**
* Resolve redirect URL for cross-domain communication
* Handles IE6/7 relative URL resolution issues
*/
checkRedirectURL(): void;
}
/**
* Proxy page functions (respond-proxy.html)
*/
interface ProxyPageAPI {
/**
* Parse query string parameters from proxy page URL
* @returns Object containing url and css parameters
*/
getQueryString(): { url: string; css: string };
/**
* AJAX function for fetching CSS from external domain
* @param url - CSS file URL to fetch
* @param callback - Function called with CSS content
*/
ajax(url: string, callback: (response: string) => void): void;
/**
* XMLHttpRequest factory function with fallbacks
* @returns XMLHttpRequest instance for current browser
*/
xmlHttp(): XMLHttpRequest;
}Uses iframe-based communication to securely fetch cross-domain CSS content.
/**
* Create iframe proxy for cross-domain CSS fetching
* @param url - External CSS file URL to fetch
* @param callback - Function called with retrieved CSS content
*/
function fakejax(url: string, callback: (css: string) => void): void;
/**
* Check and resolve base URL for relative paths
* @param href - URL to check against base element
* @returns Resolved absolute URL
*/
function checkBaseURL(href: string): string;# Upload to external domain (CDN)
scp respond-proxy.html user@cdn.example.com:/var/www/html/
# Upload to local domain
scp respond.proxy.gif user@local.example.com:/var/www/html/assets/
scp respond.proxy.js user@local.example.com:/var/www/html/js/<!DOCTYPE html>
<html>
<head>
<!-- External stylesheet that needs proxy -->
<link rel="stylesheet" href="http://cdn.example.com/styles/main.css" />
<!-- Proxy configuration -->
<link href="http://cdn.example.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
<link href="/assets/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />
<!-- Load proxy script -->
<script src="/js/respond.proxy.js"></script>
</head>
<body>
<!-- Content -->
</body>
</html>// Check if proxy elements are properly configured
var proxyLink = document.getElementById('respond-proxy');
var redirectLink = document.getElementById('respond-redirect');
if (proxyLink && redirectLink) {
console.log('Proxy configuration found');
console.log('Proxy URL:', proxyLink.href);
console.log('Redirect URL:', redirectLink.href);
} else {
console.error('Missing proxy configuration elements');
}http://cdn.example.com/respond-proxy.html?url=REDIRECT_URL&css=CSS_URL
Where:
- REDIRECT_URL: Encoded local redirect URL (respond.proxy.gif)
- CSS_URL: Encoded external CSS file URL to fetchhttp://cdn.example.com/respond-proxy.html?url=http%3A//local.com/respond.proxy.gif&css=http%3A//cdn.example.com/styles/responsive.css/**
* Check if stylesheet is external and needs proxy processing
* @param href - Stylesheet URL to check
* @returns true if external domain, false if same domain
*/
function isExternalStylesheet(href: string): boolean;Detection Logic:
// External domain patterns that trigger proxy:
var externalPatterns = [
/^([a-zA-Z:]*\/\/(www\.)?)/, // Absolute URLs with protocol
/^\/\// // Protocol-relative URLs
];
// Same domain indicators (no proxy needed):
// - Relative paths: ./styles/main.css, ../css/theme.css
// - Absolute paths: /css/main.css
// - Same host: http://currentdomain.com/css/main.css// iframe creation and cleanup
function createProxyIframe() {
var iframe;
if ("ActiveXObject" in window) {
// IE-specific iframe creation
var AXO = new ActiveXObject("htmlfile");
AXO.open();
AXO.write('<iframe id="x"></iframe>');
AXO.close();
iframe = AXO.getElementById("x");
} else {
// Standard iframe creation
iframe = document.createElement("iframe");
iframe.style.cssText = "position:absolute;top:-99em";
document.documentElement.insertBefore(iframe,
document.documentElement.firstElementChild);
}
return iframe;
}function checkFrameName(iframe, callback) {
var cssText;
try {
// CSS content is returned via iframe name property
cssText = iframe.contentWindow.name;
} catch (e) {
// Cross-domain access denied - continue polling
}
if (cssText) {
// Clean up iframe
iframe.src = "about:blank";
iframe.parentNode.removeChild(iframe);
// Process retrieved CSS
callback(cssText);
} else {
// Continue polling for response
setTimeout(function() {
checkFrameName(iframe, callback);
}, 100);
}
}The proxy system works within browser security constraints:
<!-- HTTPS configuration -->
<link href="https://secure-cdn.example.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
<link href="/assets/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />Protocol matching is important:
Problem: Proxy fails if respond-proxy.html has query parameters appended.
<!-- Incorrect -->
<link href="http://cdn.com/respond-proxy.html?version=1.0" id="respond-proxy" rel="respond-proxy" />
<!-- Correct -->
<link href="http://cdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />Problem: <base> element affects URL resolution.
<!-- Base element can interfere with proxy URLs -->
<base href="/app/" />
<!-- Solution: Use absolute URLs for proxy configuration -->
<link href="http://cdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
<link href="http://local.com/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />Problem: Mixed HTTP/HTTPS protocols cause failures.
// Automatic protocol matching
var proxyURL = location.protocol === 'https:'
? 'https://secure-cdn.com/respond-proxy.html'
: 'http://cdn.com/respond-proxy.html';
document.getElementById('respond-proxy').href = proxyURL;Problem: CSS files with no-cache headers cause repeated requests.
# Server configuration for CDN CSS files
Cache-Control: public, max-age=31536000
Expires: Thu, 31 Dec 2025 23:55:55 GMTfunction testCrossDomainSetup() {
var proxyLink = document.getElementById('respond-proxy');
var redirectLink = document.getElementById('respond-redirect');
var externalStylesheets = [];
// Check required elements
if (!proxyLink) {
console.error('Missing respond-proxy link element');
return false;
}
if (!redirectLink) {
console.error('Missing respond-redirect link element');
return false;
}
// Find external stylesheets
var links = document.getElementsByTagName('link');
for (var i = 0; i < links.length; i++) {
var link = links[i];
if (link.rel.indexOf('stylesheet') >= 0) {
var isExternal = /^([a-zA-Z:]*\/\/)/.test(link.href) &&
link.href.indexOf(location.host) === -1;
if (isExternal) {
externalStylesheets.push(link.href);
}
}
}
console.log('External stylesheets found:', externalStylesheets);
console.log('Proxy URL:', proxyLink.href);
console.log('Redirect URL:', redirectLink.href);
return externalStylesheets.length > 0;
}
// Run test
testCrossDomainSetup();Install with Tessl CLI
npx tessl i tessl/npm-respond-js