将http缓存解码为普通的html页面

时间:2016-05-20 17:15:44

标签: javascript html google-chrome caching

我正在尝试将此http缓存转换为普通的html页面,以便我可以看到内容。

以下是我要转换的http缓存:http://mediapreset.com/http-cache.log

有这个网站可以帮助将http缓存页面转换为普通的html页面,但是他们的服务不起作用:

http://www.sensefulsolutions.com/2012/01/viewing-chrome-cache-easy-way.html

然而他们提供了这个功能:

(function() {
    var preTags = document.getElementsByTagName('pre');
    var preWithHeaderInfo = preTags[0];
    var preWithContent = preTags[2];

    var lines = preWithContent.textContent.split('\n');

    // get data about the formatting (changes between different versions of chrome)
    var rgx = /^(0{8}:\s+)([0-9a-f]{2}\s+)[0-9a-f]{2}/m;
    var match = rgx.exec(lines[0]);

    var text = '';
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i];
        var firstIndex = match[1].length; // first index of the chars to match (e.g. where a '84' would start)
        var indexJump = match[2].length; // how much space is between each set of numbers
        var totalCharsPerLine = 16;
        index = firstIndex;
        for (var j = 0; j < totalCharsPerLine; j++) {
            var hexValAsStr = line.substr(index, 2);
            if (hexValAsStr == '  ') {
                // no more chars
                break;
            }

            var asciiVal = parseInt(hexValAsStr, 16);
            text += String.fromCharCode(asciiVal);

            index += indexJump;
        }
    }

    var headerText = preWithHeaderInfo.textContent;
    var elToInsertBefore = document.body.childNodes[0];
    var insertedDiv = document.createElement("div");
    document.body.insertBefore(insertedDiv, elToInsertBefore);

    // find the filename
    var nodes = [document.body];
    var filepath = '';
    while (true) {
        var node = nodes.pop();
        if (node.hasChildNodes()) {
            var children = node.childNodes;
            for (var i = children.length - 1; i >= 0; i--) {
                nodes.push(children[i]);
            }
        }

        if (node.nodeType === Node.TEXT_NODE && /\S/.test(node.nodeValue)) {
            // 1st depth-first text node (with non-whitespace chars) found
            filepath = node.nodeValue;
            break;
        }
    }

    outputResults(insertedDiv, convertToBase64(text), filepath, headerText);

    insertedDiv.appendChild(document.createElement('hr'));

    function outputResults(parentElement, fileContents, fileUrl, headerText) {
        // last updated 1/27/12
        var rgx = /.+\/([^\/]+)/;
        var filename = rgx.exec(fileUrl)[1];

        // get the content type
        rgx = /content-type: (.+)/i;
        var match = rgx.exec(headerText);
        var contentTypeFound = match != null;
        var contentType = "text/plain";
        if (contentTypeFound) {
            contentType = match[1];
        }

        var dataUri = "data:" + contentType + ";base64," + fileContents;

        // check for gzipped file
        var gZipRgx = /content-encoding: gzip/i;
        if (gZipRgx.test(headerText)) {
            filename += '.gz';
        }

        // check for image
        var imageRgx = /image/i;
        var isImage = imageRgx.test(contentType);

        // create link
        var aTag = document.createElement('a');
        aTag.textContent = "Left-click to download the cached file";
        aTag.setAttribute('href', dataUri);
        aTag.setAttribute('download', filename);
        parentElement.appendChild(aTag);
        parentElement.appendChild(document.createElement('br'));

        // create image
        if (isImage) {
            var imgTag = document.createElement('img');
            imgTag.setAttribute("src", dataUri);
            parentElement.appendChild(imgTag);
            parentElement.appendChild(document.createElement('br'));
        }

        // create warning
        if (!contentTypeFound) {
            var pTag = document.createElement('p');
            pTag.textContent = "WARNING: the type of file was not found in the headers... defaulting to text file.";
            parentElement.appendChild(pTag);
        }
    }

    function getBase64Char(base64Value) {
        if (base64Value < 0) {
            throw "Invalid number: " + base64Value;
        } else if (base64Value <= 25) {
            // A-Z
            return String.fromCharCode(base64Value + "A".charCodeAt(0));
        } else if (base64Value <= 51) {
            // a-z
            base64Value -= 26; // a
            return String.fromCharCode(base64Value + "a".charCodeAt(0));
        } else if (base64Value <= 61) {
            // 0-9
            base64Value -= 52; // 0
            return String.fromCharCode(base64Value + "0".charCodeAt(0));
        } else if (base64Value <= 62) {
            return '+';
        } else if (base64Value <= 63) {
            return '/';
        } else {
            throw "Invalid number: " + base64Value;
        }
    }

    function convertToBase64(input) {
        // http://en.wikipedia.org/wiki/Base64#Example
        var remainingBits;
        var result = "";
        var additionalCharsNeeded = 0;

        var charIndex = -1;
        var charAsciiValue;
        var advanceToNextChar = function() {
            charIndex++;
            charAsciiValue = input.charCodeAt(charIndex);
            return charIndex < input.length;
        };

        while (true) {
            var base64Char;

            // handle 1st char
            if (!advanceToNextChar()) break;
            base64Char = charAsciiValue >>> 2;
            remainingBits = charAsciiValue & 3; // 0000 0011
            result += getBase64Char(base64Char); // 1st char
            additionalCharsNeeded = 3;

            // handle 2nd char
            if (!advanceToNextChar()) break;
            base64Char = (remainingBits << 4) | (charAsciiValue >>> 4);
            remainingBits = charAsciiValue & 15; // 0000 1111
            result += getBase64Char(base64Char); // 2nd char
            additionalCharsNeeded = 2;

            // handle 3rd char
            if (!advanceToNextChar()) break;
            base64Char = (remainingBits << 2) | (charAsciiValue >>> 6);
            result += getBase64Char(base64Char); // 3rd char
            remainingBits = charAsciiValue & 63; // 0011 1111
            result += getBase64Char(remainingBits); // 4th char
            additionalCharsNeeded = 0;
        }

        // there may be an additional 2-3 chars that need to be added
        if (additionalCharsNeeded == 2) {
            remainingBits = remainingBits << 2; // 4 extra bits
            result += getBase64Char(remainingBits) + "=";
        } else if (additionalCharsNeeded == 3) {
            remainingBits = remainingBits << 4; // 2 extra bits
            result += getBase64Char(remainingBits) + "==";
        } else if (additionalCharsNeeded != 0) {
            throw "Unhandled number of additional chars needed: " + additionalCharsNeeded;
        }

        return result;
    }
    })()

如何使用上述功能进行http缓存转换?

这是我正在努力的小提琴:https://jsfiddle.net/emporio/9jdw8r68/2/

1 个答案:

答案 0 :(得分:1)

这是一个修改后的版本,可以将解压缩的数据输出到控制台:

(function convertCache() {
    var preTags = document.querySelectorAll('script[type="http-cache"]');
    var preWithHeaderInfo = preTags[0];
    var preWithContent = preTags[1];

    var lines = preWithContent.textContent.split('\n');

    // get data about the formatting (changes between different versions of chrome)
    var rgx = /^(0{8}:\s+)([0-9a-f]{2}\s+)[0-9a-f]{2}/m;
    var match = rgx.exec(lines[0]);

    var text = '';
    var data = [];
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i];
        var firstIndex = match[1].length; // first index of the chars to match (e.g. where a '84' would start)
        var indexJump = match[2].length; // how much space is between each set of numbers
        var totalCharsPerLine = 16;
        index = firstIndex;
        for (var j = 0; j < totalCharsPerLine; j++) {
            var hexValAsStr = line.substr(index, 2);
            if (hexValAsStr == '  ') {
                // no more chars
                break;
            }

            var asciiVal = parseInt(hexValAsStr, 16);
            data.push(asciiVal);
            text += String.fromCharCode(asciiVal);

            index += indexJump;
        }
    }

    var headerText = preWithHeaderInfo.textContent;
    var elToInsertBefore = document.body.childNodes[0];
    var insertedDiv = document.createElement("div");
    document.body.insertBefore(insertedDiv, elToInsertBefore);

    // find the filename
    var nodes = [document.body];
    var filepath = '';
    while (true) {
        var node = nodes.pop();
        if (node.hasChildNodes()) {
            var children = node.childNodes;
            for (var i = children.length - 1; i >= 0; i--) {
                nodes.push(children[i]);
            }
        }

        if (node.nodeType === Node.TEXT_NODE && /\S/.test(node.nodeValue)) {
            // 1st depth-first text node (with non-whitespace chars) found
            filepath = node.nodeValue;
            break;
        }
    }

    var gZipRgx = /content-encoding: gzip/i;
    if (gZipRgx.test(headerText)) {
        var binData = new Uint8Array(data);
        var data = pako.ungzip(binData);
        var strData = String.fromCharCode.apply(null, new Uint8Array(data));
        console.log(strData);
    }

    outputResults(insertedDiv, convertToBase64(text), filepath, headerText);

    insertedDiv.appendChild(document.createElement('hr'));

    function outputResults(parentElement, fileContents, fileUrl, headerText) {
        // last updated 1/27/12
        var rgx = /.+\/([^\/]+)/;
        var filename = rgx.exec(fileUrl)[1];

        // get the content type
        rgx = /content-type: (.+)/i;
        var match = rgx.exec(headerText);
        var contentTypeFound = match != null;
        var contentType = "text/plain";
        if (contentTypeFound) {
            contentType = match[1];
        }

        var dataUri = "data:" + contentType + ";base64," + fileContents;

        // check for gzipped file
        var gZipRgx = /content-encoding: gzip/i;
        if (gZipRgx.test(headerText)) {
            filename += '.gz';
        }

        // check for image
        var imageRgx = /image/i;
        var isImage = imageRgx.test(contentType);

        // create link
        var aTag = document.createElement('a');
        aTag.textContent = "Left-click to download the cached file";
        aTag.setAttribute('href', dataUri);
        aTag.setAttribute('download', filename);
        parentElement.appendChild(aTag);
        parentElement.appendChild(document.createElement('br'));

        // create image
        if (isImage) {
            var imgTag = document.createElement('img');
            imgTag.setAttribute("src", dataUri);
            parentElement.appendChild(imgTag);
            parentElement.appendChild(document.createElement('br'));
        }

        // create warning
        if (!contentTypeFound) {
            var pTag = document.createElement('p');
            pTag.textContent = "WARNING: the type of file was not found in the headers... defaulting to text file.";
            parentElement.appendChild(pTag);
        }
    }

    function getBase64Char(base64Value) {
        if (base64Value < 0) {
            throw "Invalid number: " + base64Value;
        } else if (base64Value <= 25) {
            // A-Z
            return String.fromCharCode(base64Value + "A".charCodeAt(0));
        } else if (base64Value <= 51) {
            // a-z
            base64Value -= 26; // a
            return String.fromCharCode(base64Value + "a".charCodeAt(0));
        } else if (base64Value <= 61) {
            // 0-9
            base64Value -= 52; // 0
            return String.fromCharCode(base64Value + "0".charCodeAt(0));
        } else if (base64Value <= 62) {
            return '+';
        } else if (base64Value <= 63) {
            return '/';
        } else {
            throw "Invalid number: " + base64Value;
        }
    }

    function convertToBase64(input) {
        // http://en.wikipedia.org/wiki/Base64#Example
        var remainingBits;
        var result = "";
        var additionalCharsNeeded = 0;

        var charIndex = -1;
        var charAsciiValue;
        var advanceToNextChar = function() {
            charIndex++;
            charAsciiValue = input.charCodeAt(charIndex);
            return charIndex < input.length;
        };

        while (true) {
            var base64Char;

            // handle 1st char
            if (!advanceToNextChar()) break;
            base64Char = charAsciiValue >>> 2;
            remainingBits = charAsciiValue & 3; // 0000 0011
            result += getBase64Char(base64Char); // 1st char
            additionalCharsNeeded = 3;

            // handle 2nd char
            if (!advanceToNextChar()) break;
            base64Char = (remainingBits << 4) | (charAsciiValue >>> 4);
            remainingBits = charAsciiValue & 15; // 0000 1111
            result += getBase64Char(base64Char); // 2nd char
            additionalCharsNeeded = 2;

            // handle 3rd char
            if (!advanceToNextChar()) break;
            base64Char = (remainingBits << 2) | (charAsciiValue >>> 6);
            result += getBase64Char(base64Char); // 3rd char
            remainingBits = charAsciiValue & 63; // 0011 1111
            result += getBase64Char(remainingBits); // 4th char
            additionalCharsNeeded = 0;
        }

        // there may be an additional 2-3 chars that need to be added
        if (additionalCharsNeeded == 2) {
            remainingBits = remainingBits << 2; // 4 extra bits
            result += getBase64Char(remainingBits) + "=";
        } else if (additionalCharsNeeded == 3) {
            remainingBits = remainingBits << 4; // 2 extra bits
            result += getBase64Char(remainingBits) + "==";
        } else if (additionalCharsNeeded != 0) {
            throw "Unhandled number of additional chars needed: " + additionalCharsNeeded;
        }

        return result;
    }
})()

https://jsfiddle.net/9jdw8r68/6/

来自chrome://缓存信息的数据必须拆分为两个单独的script标记(每个标记都带有type="http-cache"属性)。当您打开特定网址的缓存并检查网页源代码时,您会看到三个pre标记。

  1. 将第一个pre的内容复制到第一个script type="http-cache"代码
  2. 忽略第二个pre代码
  3. 将第三个pre的内容复制到第二个script type="http-cache"代码
  4. 忽略其余的
  5. 不幸的是,如果数据太大,它就会抛出。你必须找到不同的gzip实现,或者把它放到webworker中来解决这个问题。