该的WebRTC API可用于检索客户端的本地IP。
但是浏览器可能不支持它,或者客户端可能出于安全原因禁用了它。无论如何,从长远来看,人们不应该依赖这种“黑客”,因为它可能会在未来得到修补(参见 Cullen Fluffy Jennings 的回答)。
下面的 ECMAScript 6 代码演示了如何做到这一点。
/* ES6 */
const findLocalIp = (logInfo = true) => new Promise( (resolve, reject) => {
    window.RTCPeerConnection = window.RTCPeerConnection 
                            || window.mozRTCPeerConnection 
                            || window.webkitRTCPeerConnection;
    if ( typeof window.RTCPeerConnection == 'undefined' )
        return reject('WebRTC not supported by browser');
    let pc = new RTCPeerConnection();
    let ips = [];
    pc.createDataChannel("");
    pc.createOffer()
     .then(offer => pc.setLocalDescription(offer))
     .catch(err => reject(err));
    pc.onicecandidate = event => {
        if ( !event || !event.candidate ) {
            // All ICE candidates have been sent.
            if ( ips.length == 0 )
                return reject('WebRTC disabled or restricted by browser');
            return resolve(ips);
        }
        let parts = event.candidate.candidate.split(' ');
        let [base,componentId,protocol,priority,ip,port,,type,...attr] = parts;
        let component = ['rtp', 'rtpc'];
        if ( ! ips.some(e => e == ip) )
            ips.push(ip);
        if ( ! logInfo )
            return;
        console.log(" candidate: " + base.split(':')[1]);
        console.log(" component: " + component[componentId - 1]);
        console.log("  protocol: " + protocol);
        console.log("  priority: " + priority);
        console.log("        ip: " + ip);
        console.log("      port: " + port);
        console.log("      type: " + type);
        if ( attr.length ) {
            console.log("attributes: ");
            for(let i = 0; i < attr.length; i += 2)
                console.log("> " + attr[i] + ": " + attr[i+1]);
        }
        console.log();
    };
} );
注意我写return resolve(..)或return reject(..)作为快捷方式。这两个函数都不返回任何内容。
那么你可能会有这样的事情:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Local IP</title>
</head>
<body>
    <h1>My local IP is</h1>
    <p id="ip">Loading..</p>
    <script src="ip.js"></script>
    <script>
    let p = document.getElementById('ip');
    findLocalIp().then(
        ips => {
            let s = '';
            ips.forEach( ip => s += ip + '<br>' );
            p.innerHTML = s;
        },
        err => p.innerHTML = err
    );
    </script>
</body>
</html>