end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

zipファイルをhttp getし、zip解凍後、プレビュー表示

先日、javascriptで、zip圧縮解凍やbase64エンコーディングができることを知ったので、
1) zipファイルをhttp getし、 2) zip解凍後、 3)プレビュー表示 してみました。

といっても、次のurlの写経です。

http://hinata.in/blog/20101003214439.html
http://ascii.jp/elem/000/000/569/569180/index-4.html

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/common.css">
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>

<!-- http://blog.livedoor.jp/dankogai/archives/51067688.html -->
<script type="text/javascript" src="js/base64.js"></script>

<!-- http://hinata.in/blog/20101003214439.html -->
<!-- http://lab.gkbr.me/zipjs/  -->
<script type="text/javascript" src="js/zip.js"></script>

<script type="text/javascript" src="js/view_zip.js"></script>
</head>

<body>
zipファイルのあるurlを指定し、クリックして下さい。<br>
<input type="text" id="zip_url" value="data/test.zip" size="20">
<input type="button" value="ANALYZE ZIP" onclick="zip.load_zip('#zip_url')">

<div id="zip_items"></div>
</body>
</html>
function ViewZip(){
    //拡張子からcontent_typeを判断
    this.get_content_type_by_filename = function(filename){
        var extension = filename.split(".").pop();

        var types = {
	    jpg :  "image/jpeg",
	    png :  "image/png",
	    txt :  "text/plain",
	    html : "text/html"
	};
        return types[extension];
    };

    //zipをhttp getし、zip内のファイルを表示
    this.load_zip = function(selecter){
        var url = $(selecter).val();

        var xhr = new XMLHttpRequest();
        xhr.open("GET",url);

        var this_obj = this;

        xhr.onload = function (){
            $('#zip_items').html('');

            var bin = xhr.responseText;
            var bytes = [];
            for (var i = 0; i < bin.length; i++){
                //後で charset=x-user-defined としているので
                //0xffとの論理積を取る必要があるらしい...
                bytes[i] = bin.charCodeAt(i) & 0xff;
            }
            var zip = Zip.inflate(bytes);  //UNZIP

	    for ( var j in zip.files ) {
		var file = zip.files[j];
                
                $('#zip_items').append( $('<div></div>') );

                if (file.name.match(/\/$/) ) {
                    $('#zip_items>div:last')
                        .append( 'dir : '+ file.name );
                    continue;
                }
                
                var content_type =
                    this_obj.get_content_type_by_filename(file.name);

                //filenameが日本語の場合、どうなるのだろう?
                $('#zip_items>div:last')
                    .append(' name:'+ file.name+ 
                            ' type:'+ content_type +
                            ' size:'+ file.fileSize+ 'byte' +
                            ' modified:'+ file.modified+ '<br>' );

                //dankogaiさんのbase64.jsでbynary to utf8
                if (content_type=='text/plain'){
                    $('#zip_items>div:last')
                        .append('<textarea cols=60 rows=3>'+
                                Base64.btou(file.data)+'</textarea>');
                } else if (content_type=='text/html'){
                    //iframeやimgでは、src属性にbase64値をsetできるらしい
                    $('#zip_items>div:last')
                        .append("<iframe src='" +
                                "data:" + content_type +";base64," + btoa(file.data) +
                                "'></iframe>");
                } else if (content_type.indexOf("image/") == 0){
                    //iframeやimgでは、src属性にbase64値をsetできるらしい
                    $('#zip_items>div:last')
                        .append("<img src='" +
                                "data:" + content_type +";base64," + btoa(file.data) +
                                "'/>");
                }
	    }
        };
        xhr.overrideMimeType("text/plain;charset=x-user-defined");
        xhr.send(null);
    };
};

var zip = new ViewZip();
#zip_items {
    border: 1px solid #000000;
    padding: 5px;
}

#zip_items div {
    border: 1px solid #000000;
    margin-top: 5px;
    padding: 5px;
}

iframe {
    width: 400px;
    height: 100px;
}

テストに使用したファイル構成

|-- img
|   `-- user.jpg
|-- index.html
|-- null_dir
`-- utf8.txt

実行結果

私のこれまでのjavascriptに対する考え方が変わってきた気がします。