M.C.P.C.

―むり・くり―プラスコミュニケーション(更新終了)


| トップページ |

2008年11月 1日 18:13

HttpConnectionクラス互換HttpConnクラスを作っているのだがJavaScriptで文字列のキャラクターエンコーディング変換する方法が不明

このエントリーをはてなブックマークに追加 mixiチェック

Adobe ExtendScript2、Adobe Bridge CS3、Adobe InDesign CS3などで動くJavaScriptで、

/*
if ( !ExternalObject.webaccesslib ) {
ExternalObject.webaccesslib = new ExternalObject('lib:webaccesslib');
}
*/
 
function HttpConn(url) {
    // コンストラクタ。ここでUser-Agent名や
    // timeout値など準備しておくといいよね
    this.url  = url;
    this.timeout = 5;
    this.redirect = 5;
    this.method = "GET";
    this.responseStatus = undefined;
    this.responseheaders = {};
    this.requestheaders = {};
    this._count = 0;
};
HttpConn.uri = function(uri) {
    var rex = new RegExp( 'http://([^:/]+)(?::(\d+))?(.+)' );
      // via http://pc11.2ch.net/test/read.cgi/php/1015692614/57
    var urlObj =[];
    if ( uri.match(rex) ) {
        urlObj.host = RegExp.$1;
        urlObj.port = RegExp.$2 ?RegExp.$2 :80;
        urlObj.path = RegExp.$3;
    }
    return urlObj;
};
HttpConn.prototype.execute = function () {
    var conn = new Socket;
    conn.timeout = this.timeout;
    var urlObj = HttpConn.uri(this.url);
    if (conn.open( urlObj.host + ':' + urlObj.port, 'binary' ) ) {
        var requestHeader ="";
        for (var i = 0; i < this.requestheaders.length / 2; i++) {
            requestHeader = this.requestheaders[i] +": "
            + this.requestheaders[i+1] + "\n";
        }
         conn.write ( this.method + " " + urlObj.path
        + " HTTP/1.0\n"
        + 'Host: ' + urlObj.host + "\n"
        + requestHeader
        + "\n");
        var reply = "";
        for ( ; ; ) {
            if (conn.eof) break;
            reply += conn.read(65536);
        }
        conn.close();
        var boundary =[];
        boundary[0]
        = reply.indexOf("\r\n"); //responseStatus/ResponseHeader
        boundary[1]
        = reply.indexOf("\r\n\r\n"); // responseHeader/body
        var response = {
            status: reply.substring(0, boundary[0]),
            header: reply.substring(boundary[0]+2, boundary[1]),
            body: reply.substring(boundary[1] + 4 ),
        }
        // response
        if (typeof(this.response) !="undefined"
            && this.response.constructor.name == "File") {
            this.response.open("w");
            this.response.write(response.body);
        }
        else {
            this.response = response.body;
        }
        var headerArray
        = response.header.substring(boundary[0] + 2).split("\n"); 
        this.responseheaders = [];
        var headerArrayPair = [];
        // responseheaders
        for (var i = 0; i < headerArray.length;i++) {
            if (headerArray[i].match(/(^.+?):(.+)/) ) {
                headerArrayPair.push( [RegExp.$1, RegExp.$2] );
            }
        }
        headerArrayPair.sort(function(a, b) {
            return (a[0] > b[0]) ? 1 : -1;
        });
        for (var i = 0; i < headerArrayPair.length; i++) {
                this.responseheaders.push( 
                    headerArrayPair[i][0], headerArrayPair[i][1] );
        }
        // responseStatus
        response.status.match(/(^HTTP\/\d\.\d) (\d+) (.+)/);
        this.responseStatus = RegExp.$2;
        if (this.responseStatus == "301"
        || this.responseStatus == "302") {
            var url = "";
            for (var i = 0;  i < this.responseheaders.length; i+=2) {
                if (this.responseheaders[i] == "Location") {
                    url = this.responseheaders[i+1];
                    break;
                }
            }
            var http = new HttpConn(url);
            http.requestheaders = [ "User-Agent",
                app.name + "/" + app.version + " "
                + "(" + $.os + ")",
            ];
            http.execute() ;
            this.response = http.response;
            this.responseStatus = http.responseStatus;
        }
        return;
    } else {
        this.responseStatus = -1;
    }
};
 
 
var http = new HttpConn("http://www.yahoo.co.jp/");
http.requestheaders = [    "User-Agent",
    app.name + "/" + app.version + " "
    + "(" + $.os + ")",
 ];
//http.response = new File("/c/temp/robin.shtml");
 
http.execute();
 
alert(http.responseStatus);
alert(http.response);
 
// http.response.close();

てな感じで、HttpConnectionクラスのただWebから引っ張ってくるところだけ互換で使えるようなクラスHttpConnクラスを作っているんだけれども、今途中で止まっているのは、binaryで引っ張ってきてStringとして入れたコンテンツを如何にしてエンコーディングを変換しようか、ていうところです。Perlだったら、decode("utf8", $reply)の一文で済みそうなところなんだけれども、JavaScriptってどうすればいいんやろう。

投稿 大野 義貴 [Script] | |

トラックバック(0)

トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/2648

コメント(2)

Escape Codec Library: ecl.js
http://nurucom-archives.hp.infoseek.co.jp/digital/escape-codec-library.html

ってのがあるですけれど、ExtendScript Toolkit 2では動作しない模様。
当方、cookieの出し入れに使ったことがあるので、ブラウザ上で動作するのは確認済み。

Escape Codec Library: ecl.js
http://nurucom-archives.hp.infoseek.co.jp/digital/escape-codec-library.html

これは、Webアプリ作っているときに利用を検討したことがあります。Adobeの実行系だと動かないんですね……。

そんで、エンコーディングが用意されているとかいうので、Fileクラスの入出力の時に変換できるようですから、テンポラリファイルを使うことにして、

// reply には Socketで取得したコンテンツが入ってる
var tempFileName = Folder.temp+ "/" + "temp.dat";
var tempFile = new File(tempFileName);
tempFile.encoding = "BINARY";
tempFile.open("w");
tempFile.write(reply);
tempFile.close();
tempFile = new File(tempFileName);
tempFile.open("r");
tempFile.encoding = "EUC-JP";
reply = tempFile.read();
tempFile.close();
alert(reply);

とかやってみていますがなかなかうまくいきませんね。

コメントする