1

単純な問題

Google Drive API のサムネイルがあり、有効期限があるためコピーを保存する必要があります。

環境

管理者がウェブサイトにコンテンツを追加するためのバックエンドを構築しており、リソース管理ツールとして Google ドライブを使用しています。私は Meteor で実行しているので、サーバー側の Nodejs です。

試み

  1. よく知られているキャンバス メソッドを使用して、データ URL を取得します。

    getImageDataURL = function (URL, cb) {
    
        var img = document.createElement("img");
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
    
        img.setAttribute('crossorigin','anonymous');
    
        img.onload = function () {
            canvas.width = this.width;
            canvas.height = this.height;
            ctx.drawImage(img, 0, 0);
            cb && cb(canvas.toDataURL("image/jpg"));
        };
    
        img.src = URL;
    
    };
    

    ただし、CORS の制限により失敗します (サムネイルは Google ドメインから取得されます)。

  2. "Okay, so since it'll be stored on the server, I might as well do the job directly there."画像コンテンツを取得することは問題ありませんでしたが、いくつかの不明な暗い呪いで、コンテンツを適切な base64 形式に変換することができませんでした。結果の文字列は予想される出力とほぼ同じですが、文字の不一致が約 10% あります... base64 変換を行うために膨大な量の関数を試しましたが、正しく取得できません。私は正しいと思うこの単純なコードの魔女になってしまいました。コンテンツのエンコーディングに欠けているものがあります... (これは流星のコードで、collection-hooks パッケージを使用しています)

    Medias.before.insert(function (userId, doc) {
        var res = HTTP.get(doc.thumb);
        doc.thumb = "data:"+res.headers["content-type"]+";base64,"+new Buffer(res.content, 'ascii').toString('base64');
    });
    

    Buffer ラッパーの有無にかかわらず、可能なすべての Buffer エンコーディング パラメータを使用して試してみました。「ascii」は、次のような他のレガシー変換関数と比較して正しい出力を生成するものです: http://hellerim.net/base64_src.php

  3. "Proxy the god damn image then!"はい、試してみましたが、html ヘッダーで問題が発生しました... (http-methods パッケージ)

    HTTP.methods({
        '/getImage/:url': function(){
            var req = HTTP.get(this.params.url);
    
            this.addHeader('access-control-allow-origin', '*');
            this.addHeader('content-disposition', req.headers['content-disposition']);
            this.addHeader('content-type', req.headers['content-type']);
            //this.addHeader('content-length', req.headers['content-length']);
    
            return req.content;
        }
    });
    

    「コンテンツタイプ」を設定しない場合、もちろんテキストとしてデータを取得します。そうでなければ、何も得られません。"Right, this is because 'content-length' is missing!"...追加すると、素敵なエラーでサーバーがクラッシュしますCan't render headers after they are sent to the client。私は流星の専門家ではなく、テーブルの下で何が起こっているのかまったくわかりません。いくつかのヘッダーが自動的に追加されている必要があり、コンテンツの長さを任意に定義して何らかのプロセスを台無しにしているに違いありません。

  4. "Wow, dude, you like it hard! Why don't you just store them as files?"まず、管理がはるかに簡単であり、dataURL を使用することがサムネイルをすばやく表示するのに最適であると考えているため、DB に格納することをお勧めします。第二に、流星のパブリック フォルダーへのアクセスが禁止されているため、ファイルをサーバー上の別の場所に手動で保存する必要があるため、魔女は醜く、それらの取得を許可するアクセス ポイントを提供します。さらに、mongodb の gridfs ファイル ストレージを試しました。meteor ラッパー (CollectionFS パッケージ) はバグが多く、単にサムネイルを保存するための多くのインフラストラクチャです。

だから、最初の3点に関連するアイデアを持っている人がいたら、すぐにビールを買うよ!私はこれで1週間以上立ち往生しており、弾薬がありません!

ありがとう =)

4

0 に答える 0