Temporarily unzip a file to view contents within a browser

被刻印的时光 ゝ 提交于 2020-12-06 02:59:21

问题


I want to unzip a file that contains an html page, css, and js directories. I want to unzip this temporarily and view the html in an iFrame, preferrably. I am using jszip which is working. I got the html to load, but how do I add the image, js, and css folders into the iFrame?

Here is what I have so far...

<div id="jszip_utils"></div>
<iframe id="iframe"></iframe>
<script type="text/javascript">
    function showError(elt, err) {
        elt.innerHTML = "<p class='alert alert-danger'>" + err + "</p>";
    }
    function showContent(elt, content) {
        elt.innerHTML = "<p class='alert alert-success'>loaded !<br/>" +
          "Content = " + content + "</p>";
    }
    var htmltext = JSZipUtils.getBinaryContent("/zip/myWebsite.zip", function (err, data) {
        var elt = document.getElementById('jszip_utils');
        if (err) {
            showError(elt, err);
            return;
        }
        try {
            JSZip.loadAsync(data)
                .then(function (zip) {
                    for(var name in zip.files) {
                        if (name.substring(name.lastIndexOf('.') + 1) === "html") {
                            return zip.file(name).async("string");
                        }
                    }
                    return zip.file("").async("string");
                })
                .then(function success(text) {
                    $('#iframe').contents().find('html').html(text);
                    showContent(elt, text);
                }, function error(e) {
                    showError(elt, e);
                });
        } catch(e) {
            showError(elt, e);
        }
    });
</script>

This gets the html, but the js css and image files are not showing up. I believe I need to do some sort of fake routing, but I'm not sure how I would be able to do that. Thanks for your help.


回答1:


If the html/js in the zip is not too complicated, for instance an AngularJS app that has routes for partials, this is possible.

The trick is to replace css,js,img src/href urls that point to a file in the zip with either:

  • Object Url: URL.createObjectURL(Blob or File object);
  • Data Url: data:[<mediatype>][;base64],<data>
  • Or in the case of js and css inject the content directly into the appropriate element

After replacing the src/href references than just inject the new html into the iframe.

Step 1: Parse the html so you can manipulate it

//html from a call like zip.file("index.html").async("string")
let parser = new DOMParser;
let doc = parser.parseFromString(html,"text/html");

Step 2: Find all elements with a relative path (e.g. /imgs/img.jpg) as they are easier to deal with as you can then use that path for zip.file

//Simply finds all resource elements, then filters all that dont start with '/'
var elements = jQuery("link[href],script[src],img[src]",doc).filter(function(){
   return /^\//.test(this.href || this.src);
});

Step 3: Replace src,href with object url, data url, or direct content

//assume element is the html element: <script src="/js/main.js"></script>
zip.file(element.src).async("string").then(jsText=>{
   element.src = "data:text/javascript,"+encodeURIComponent(jsText);
});

Step 4: Get the new html text and inject it into the iframe

let newHTML = doc.documentElement.outerHTML;
var viewer = document.querySelector('#iframeID');
viewer = viewer.contentWindow || viewer.contentDocument.document || viewer.contentDocument;

viewer.document.open();
viewer.document.write(html);
viewer.document.close();

JSFiddle Demo - Demonstrates replacing the src/href urls

As a security note, if you are using zip files that you do not know the contents of, you should run the whole app in a protected iframe



来源:https://stackoverflow.com/questions/37075591/temporarily-unzip-a-file-to-view-contents-within-a-browser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!