admin管理员组

文章数量:1434914

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.

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.

Share Improve this question asked May 6, 2016 at 14:58 Taylor MitchellTaylor Mitchell 6131 gold badge11 silver badges29 bronze badges 2
  • Pretty difficult. The only widely-supported way is to use a server or have the user manually download, unzip, and open the HTML page. Until recently that was the only option. If you're willing to limit patibility, you could now use service workers. – Dark Falcon Commented May 6, 2016 at 15:05
  • What you can try is: create a temporary folder in the root of your site. Unzip all the files there. Point the iframe to open www.mysite./temporary-folder. Untested and may require page to be reloaded. It goes without saying that you need to trust users on what they are uploading – Lelio Faieta Commented May 6, 2016 at 17:53
Add a ment  | 

1 Answer 1

Reset to default 2

If the html/js in the zip is not too plicated, 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

本文标签: javascriptTemporarily unzip a file to view contents within a browserStack Overflow