PAC Files Guide: Proxy Auto-Configuration Explained
A PAC (Proxy Auto-Configuration) file is a JavaScript file that tells browsers and applications which proxy server to use for each URL request. Instead of applying a single proxy to all traffic, PAC files enable intelligent routing — sending some requests through proxies while allowing others to connect directly. This is essential for corporate networks, development environments, and sophisticated proxy setups.
How PAC Files Work
When a browser is configured to use a PAC file, it calls the FindProxyForURL() function for every URL request. The function evaluates the URL and host, then returns instructions on which proxy to use (or whether to connect directly).
Browser Request Flow with PAC:
1. User navigates to https://example.com/page
2. Browser calls: FindProxyForURL("https://example.com/page", "example.com")
3. PAC function evaluates rules
4. Returns: "PROXY proxy.company.com:8080" or "DIRECT"
5. Browser routes traffic accordinglyPAC File Syntax
Basic Structure
function FindProxyForURL(url, host) {
// url = full URL being requested
// host = hostname extracted from URL
// Return values:
// "DIRECT" — connect without proxy
// "PROXY host:port" — use HTTP proxy
// "SOCKS host:port" — use SOCKS proxy
// "SOCKS5 host:port" — use SOCKS5 proxy
// Multiple: "PROXY a:8080; PROXY b:8080; DIRECT"
// → Try proxy a first, then b, then direct
return "DIRECT";
}Simple PAC File Examples
Route specific domains through proxy
function FindProxyForURL(url, host) {
// Internal sites go direct
if (dnsDomainIs(host, ".internal.company.com") ||
dnsDomainIs(host, ".local")) {
return "DIRECT";
}
// Specific sites through proxy
if (dnsDomainIs(host, ".target-site.com") ||
dnsDomainIs(host, ".another-site.com")) {
return "PROXY scraping-proxy.example.com:8080";
}
// Everything else goes direct
return "DIRECT";
}Route all traffic except local through proxy
function FindProxyForURL(url, host) {
// Local/internal traffic bypasses proxy
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(host, "10.0.0.0", "255.0.0.0") ||
isInNet(host, "172.16.0.0", "255.240.0.0") ||
isInNet(host, "192.168.0.0", "255.255.0.0") ||
host === "localhost" ||
host === "127.0.0.1") {
return "DIRECT";
}
// All other traffic through proxy
return "PROXY proxy.company.com:8080";
}Advanced PAC Functions
PAC files have access to several built-in helper functions:
Host and Domain Matching
function FindProxyForURL(url, host) {
// dnsDomainIs — check if host is in domain
if (dnsDomainIs(host, ".google.com")) {
// Matches: www.google.com, maps.google.com
// Does NOT match: google.com (no leading dot)
}
// shExpMatch — shell expression matching (wildcards)
if (shExpMatch(host, "*.amazon.*")) {
// Matches: www.amazon.com, amazon.co.uk, api.amazon.de
}
// localHostOrDomainIs — exact or domain match
if (localHostOrDomainIs(host, "www.example.com")) {
// Matches: www.example.com, www
}
// isPlainHostName — no dots in hostname
if (isPlainHostName(host)) {
// Matches: "intranet", "server1"
// Does NOT match: "www.example.com"
return "DIRECT";
}
return "DIRECT";
}Network-Based Routing
function FindProxyForURL(url, host) {
// isInNet — check if IP is in subnet
if (isInNet(dnsResolve(host), "198.51.100.0", "255.255.255.0")) {
return "PROXY special-proxy.example.com:8080";
}
// myIpAddress — get client's IP
var myIp = myIpAddress();
if (isInNet(myIp, "10.1.0.0", "255.255.0.0")) {
// Client is in office network
return "PROXY office-proxy.company.com:8080";
}
// dnsDomainLevels — count dots in hostname
if (dnsDomainLevels(host) > 2) {
// More than 2 dots: sub.domain.example.com
}
return "DIRECT";
}URL-Based Routing
function FindProxyForURL(url, host) {
// Route based on protocol
if (url.substring(0, 5) === "http:") {
return "PROXY http-proxy.example.com:8080";
}
if (url.substring(0, 6) === "https:") {
return "PROXY https-proxy.example.com:8443";
}
if (url.substring(0, 4) === "ftp:") {
return "PROXY ftp-proxy.example.com:2121";
}
// Route based on URL path
if (shExpMatch(url, "*/api/*")) {
return "PROXY api-proxy.example.com:8080";
}
return "DIRECT";
}Real-World PAC File Templates
Web Scraping Setup
function FindProxyForURL(url, host) {
// Scraping targets → use rotating residential proxy
var scrapingTargets = [
"amazon.com", "ebay.com", "walmart.com",
"google.com", "bing.com",
"instagram.com", "tiktok.com", "facebook.com"
];
for (var i = 0; i < scrapingTargets.length; i++) {
if (dnsDomainIs(host, "." + scrapingTargets[i]) ||
host === scrapingTargets[i]) {
return "PROXY residential-gateway.provider.com:8080";
}
}
// API endpoints → use datacenter proxy (faster)
if (shExpMatch(url, "*api*") || shExpMatch(url, "*/v1/*") ||
shExpMatch(url, "*/v2/*")) {
return "PROXY datacenter-proxy.provider.com:8080";
}
// Everything else → direct connection
return "DIRECT";
}Geo-Targeted Proxy Routing
function FindProxyForURL(url, host) {
// US content → US proxy
if (dnsDomainIs(host, ".com") && !dnsDomainIs(host, ".co.uk")) {
return "PROXY us-proxy.provider.com:8080";
}
// UK content → UK proxy
if (dnsDomainIs(host, ".co.uk") || dnsDomainIs(host, ".uk")) {
return "PROXY uk-proxy.provider.com:8080";
}
// German content → DE proxy
if (dnsDomainIs(host, ".de")) {
return "PROXY de-proxy.provider.com:8080";
}
// Fallback
return "PROXY default-proxy.provider.com:8080";
}Failover Configuration
function FindProxyForURL(url, host) {
// Primary proxy, fallback to secondary, then direct
return "PROXY primary-proxy.example.com:8080; " +
"PROXY backup-proxy.example.com:8080; " +
"DIRECT";
}Hosting and Configuring PAC Files
Hosting Options
PAC files must be served with MIME type: application/x-ns-proxy-autoconfig
Options:
1. Web server (Apache/Nginx)
2. Local file (file:///path/to/proxy.pac)
3. WPAD auto-discovery
4. Corporate Group PolicyNginx Configuration
server {
listen 80;
server_name pac.company.com;
location /proxy.pac {
alias /etc/proxy/proxy.pac;
types { }
default_type application/x-ns-proxy-autoconfig;
}
}Browser Configuration
Chrome:
Settings → System → Open proxy settings → Auto proxy configuration
URL: http://pac.company.com/proxy.pac
Firefox:
Settings → Network Settings → Automatic proxy configuration URL
URL: http://pac.company.com/proxy.pac
macOS System:
System Preferences → Network → Advanced → Proxies
Check "Automatic Proxy Configuration"
URL: http://pac.company.com/proxy.pac
Windows:
Settings → Network & Internet → Proxy → Automatic proxy setup
Use setup script: On
Script address: http://pac.company.com/proxy.pacWPAD (Web Proxy Auto-Discovery)
WPAD automatically discovers PAC files using DNS or DHCP:
WPAD Discovery Process:
1. Browser looks for DHCP option 252 (WPAD URL)
2. If not found, tries DNS: wpad.company.com
3. Fetches: http://wpad.company.com/wpad.dat
4. Uses PAC file from wpad.dat
DNS setup:
wpad.company.com A 10.0.1.100 (PAC file server)Debugging PAC Files
Testing with Browser Console
// Chrome: chrome://net-internals/#proxy
// Shows PAC file status and per-URL proxy decisions
// Firefox: about:networking#dns
// Shows proxy resolution resultsTesting PAC Logic
// Create a test harness for your PAC file
function testPAC() {
var tests = [
{url: "https://www.amazon.com/product", host: "www.amazon.com",
expected: "PROXY residential-gateway.provider.com:8080"},
{url: "https://api.internal.com/v1/data", host: "api.internal.com",
expected: "DIRECT"},
{url: "https://www.google.co.uk/search", host: "www.google.co.uk",
expected: "PROXY uk-proxy.provider.com:8080"},
];
for (var i = 0; i < tests.length; i++) {
var result = FindProxyForURL(tests[i].url, tests[i].host);
var status = (result === tests[i].expected) ? "PASS" : "FAIL";
console.log(status + ": " + tests[i].url + " → " + result);
}
}Frequently Asked Questions
Are PAC files secure?
PAC files run JavaScript in a sandboxed environment with limited functionality. They cannot access the DOM, make network requests, or interact with the filesystem. However, the PAC file itself is downloaded over HTTP (usually), which means it could be modified in transit (man-in-the-middle). Host PAC files over HTTPS when possible.
What is the performance impact of PAC files?
PAC evaluation adds microseconds per request — negligible for browsing. However, dnsResolve() calls within PAC files can add significant latency (DNS lookup for every request). Avoid dnsResolve() and isInNet() with hostname arguments when possible; use domain-matching functions instead.
Can PAC files handle proxy authentication?
No. PAC files only determine which proxy to use for each URL. They cannot include authentication credentials. Authentication must be handled separately (browser prompt, proxy extension, or IP whitelisting). See our proxy authentication guide for details.
Do all browsers support PAC files?
All major browsers (Chrome, Firefox, Safari, Edge) support PAC files. However, some mobile browsers and embedded web views have limited or no PAC support. Programmatic HTTP clients (Python requests, Node.js axios) do not use PAC files by default — you must implement the routing logic in your code.
What is the difference between PAC and WPAD?
PAC (Proxy Auto-Configuration) is the JavaScript file format. WPAD (Web Proxy Auto-Discovery) is the protocol for automatically finding the PAC file on a network. WPAD uses DNS or DHCP to locate the PAC file URL without manual configuration. Think of WPAD as the delivery mechanism and PAC as the content.
Conclusion
PAC files provide intelligent, automated proxy routing that is more flexible than static proxy configuration. They are essential for environments where different destinations require different proxy handling — from corporate networks to advanced web scraping setups. Write PAC files using the built-in helper functions, avoid DNS-heavy operations for performance, and host them securely to prevent tampering.
For proxy configuration tools, see our guides on SwitchyOmega setup and FoxyProxy setup.
- Datacenter vs Residential Proxies: Complete Comparison
- Docker Proxy Setup: Configure Containers to Use Proxies
- Anti-Bot Detection Glossary: 50+ Terms Defined
- Anti-Bot Terminology Glossary: Complete A-Z Reference 2026
- Backconnect Proxies Deep Dive: Architecture and Real-World Performance
- Best Proxies in Southeast Asia: Singapore, Thailand, Indonesia, Philippines
- Datacenter vs Residential Proxies: Complete Comparison
- Docker Proxy Setup: Configure Containers to Use Proxies
- Anti-Bot Detection Glossary: 50+ Terms Defined
- Anti-Bot Terminology Glossary: Complete A-Z Reference 2026
- Backconnect Proxies Deep Dive: Architecture and Real-World Performance
- Best Proxies in Southeast Asia: Singapore, Thailand, Indonesia, Philippines
- Datacenter vs Residential Proxies: Complete Comparison
- Docker Proxy Setup: Configure Containers to Use Proxies
- 403 Forbidden Error: What It Means & How to Fix It
- 407 Proxy Authentication Required: Fix Guide
- Anti-Bot Detection Glossary: 50+ Terms Defined
- Anti-Bot Terminology Glossary: Complete A-Z Reference 2026
Related Reading
- Datacenter vs Residential Proxies: Complete Comparison
- Docker Proxy Setup: Configure Containers to Use Proxies
- 403 Forbidden Error: What It Means & How to Fix It
- 407 Proxy Authentication Required: Fix Guide
- Anti-Bot Detection Glossary: 50+ Terms Defined
- Anti-Bot Terminology Glossary: Complete A-Z Reference 2026