Using pac File for Proxy Autoconfiguration

The pac (proxy autoconfiguration) file is actually a JavaScript file, it doesn't really matter what the file extension is, but it is usually named pac.

The pac file must contain the function FindProxyForURL(url, host), and browsers that support pac autoconfiguration will use this function to determine which channel to use for the currently visited URL. The simplest example is as follows:

function FindProxyForURL(url, host) {
    return 'DIRECT';
}

The above code shows that for all URLs, it connects directly and does not take any proxy.

Besides "DIRECT", the FindProxyForURL function can also return proxies of the specified type, host, and port. For example:

// Local http proxy for port 3721
"PROXY 127.0.0.1:3721"

// local socks5 proxy for port 8080
"SOCKS5 127.0.0.1:8080"

You can specify more than one way at the same time, starting with the first one, and one cannot connect using the next one until it succeeds or finally fails, e.g:

return "PROXY 127.0.0.1:3721; SOCKS5 127.0.0.1:8080; DIRECT";

The pac file can use many functions that have been predefined, but in the current environment for dealing with blocking, a common feature is to let the blocked URLs use the proxy, a normal direct link. Therefore, a commonly used function is: shExpMatch(str, shexp).

The shExpMatch function is to determine whether the string str satisfies the shexp expression. Note that, despite its exp name, shexp is an expression that supports only ? and * wildcard expressions, not regular expressions in JavaScript, such as:

// google website by proxy, other direct connection
function FindProxyForURL(url, host) {
    if (shExpMatch(url, "*.google.com/*")) {
        return 'PROXY 127.0.0.1:3721'.
    }

    return 'DIRECT'.
}

If you need to make some more complex judgments, then you can simply discard the shExpMatch function and use regular expressions or other tools to make your own judgments, e.g:

function FindProxyForURL(url, host) {
    // For instance, if the server has 4 alphabetic characters, 
    // such as "MSDN", route it through a specific proxy: 

    var regexpr = /[a-zA-Z]{4}.microsoft.com/;
    if(regexpr.test(host))
        return "PROXY w3proxy:8080; DIRECT";

    // Or else connect directly:
    return "DIRECT";
}

Thus, when the browser supports pac auto-proxy, all that needs to be done is to write the FindProxyForURL function, collect all the website data, and enable it, e.g:

function isMatchProxy(url, pattern) {
    try {
        return new RegExp(pattern.replace('.', '\\.')).test(url);
    } catch (e) {
        return false;
    }

}

function FindProxyForURL(url, host) {
    var Proxy = 'SOCKS5 127.0.0.1:7070; DIRECT;';

    var list = [
        't.co',
        'twitter.com',
        'twimg.com',
        'posterous.com',
        'tinypic.com',
        'twitpic.com',
        'bitly.com',
        'yfrog.com',
        'youtube.com',
        'facebook.com',
        'appspot.com',
        'dropbox.com',
        'flickr.com',
        'youtube.com',
        'ytimg.com',
        'plus.google.com',
        'ggpht.com',
        'talkgadget.google.com',
        'picasaweb.google.com',
        'googleusercontent.com',
        'hzmangel.info',
        'slideshare.net',
        'code.google.com',
        'golang.org',
        'vimeo.com',
        //'appengine.google.com',
        'wordpress.com' 
    ];


    for(var i=0, l=list.length; i<l; i++) {
        if (isMatchProxy(url, list[i])) {
            return Proxy;
        }
    }
    return 'DIRECT';
}