2016-11-18 6 views
0

Google Cloud Storageを使用するプロジェクトで、Node.jsを使用してメディアファイルを定義済みのバケットにアップロードできるようにしています。私は小さなファイル.jpgでテストしてきました。また、私はgsutilを使用してバケットのアクセス許可をpublicに設定しました。Google Cloud Storage一貫性のない動作のコンテンツリンクを作成する

まず、すべてのファイルが、ファイルをダウンロードしたリンクを生成しました。ドキュメントを調査したところ、gsutil CLIを使用して、アップロード後に各ファイルのContent-Typeを明示的に設定できることを知りました。この手順を使用してファイルタイプを'image/jpeg'に設定すると、リンクの動作が変更されてブラウザにイメージが表示されます。しかしこれは、メタデータをgsutilで更新する前にリンクが以前にクリックされていない場合にのみ有効です。これはブラウザのキャッシュに起因すると考えられましたが、シークレットブラウザではその動作が重複していました。

MIMEタイプは、任意の割合で非現実的だろう設定しgsutilを使用したので、私はmimeと呼ばれるnpmモジュールを使用して、アップロード時にメタデータを設定するために、私のノードサーバPOST機能にコードを変更しました。ここでは、コードは次のとおりです。

app.post('/api/assets', multer.single('qqfile'), function (req, res, next) { 
    console.log(req.file); 

    if (!req.file) { 
     return ('400 - No file uploaded.'); 
    } 

    // Create a new blob in the bucket and upload the file data. 
    var blob = bucket.file(req.file.originalname); 
    var blobStream = blob.createWriteStream(); 
    var metadata = { 
     contentType: mime.lookup(req.file.originalname) 
    }; 

    blobStream.on('error', function (err) { 
     return next(err); 
    }); 

    blobStream.on('finish', function() { 

     blob.setMetadata(metadata, function(err, response){ 
      console.log(response); 
      // The public URL can be used to directly access the file via HTTP. 
     var publicUrl = format(
     'https://storage.googleapis.com/%s/%s', 
     bucket.name, blob.name); 
     res.status(200).send(
      { 
       'success': true, 
       'publicUrl': publicUrl, 
       'mediaLink': response.mediaLink 
      }); 
     }); 

    }); 

    blobStream.end(req.file.buffer); 

}); 

これは、実際にアップロード時にContent-Typeを設定しないと、それが正しく応答オブジェクトだけでなく、クラウドストレージコンソールに反映されている立場から、動作しているようです。問題は、publicUrlとして返されたリンクの一部がファイルのダウンロードを引き起こし、その他はブラウザの画像読み込みを引き起こすことです。理想的には、私は両方のオプションを利用できるようにしたいと思いますが、保存されたファイルやそのメタデータに違いはありません。

私はここで何が欠けていますか?

答えて

0

Google Cloud Storageでは、アップロードされたオブジェクトのコンテンツタイプについての前提はありません。指定しない場合、GCSは単に "application/octet-stream"のタイプを割り当てます。

しかし、コマンドラインツールgsutilはよりスマートで、ほとんどの場合アップロードされるファイル(JPEGが含まれている)に適切なContent-Typeを添付します。

あなたのブラウザが画像を表示するのではなくダウンロードする理由は2つあります。まず、Content-Typeが "application/octet-stream"に設定されている場合、ほとんどのブラウザは結果を表示するのではなくファイルとしてダウンロードします。これはあなたの場合に起こりそうです。

第2の理由は、サーバーが「Content-Disposition:attachment」ヘッダーで応答する場合です。これは通常、上記のようにホスト "storage.googleapis.com"からGCSオブジェクトを取得したときには発生しませんが、アップロードしたオブジェクトのcontentDispositionを明示的に指定した場合などに発生します。

あなたのオブジェクトの中には、「画像/ JPEG」のコンテンツタイプがないものがあると思われます。 gsutil -m setmeta 'Content-Type:image/jpeg' gs://myBucketName/**

+0

私はすべてのファイルが適切なMIMEタイプで正しくタグ付けされていることを確認しましたが、どれも 'application-octet-stream'タグが付けられていないことを確認しました。さらに、 'Content-Disposition'の値が設定されていないことを確認しましたが、過度のためにメタデータでnullとしてタグ付けする行をサーバーコードに明示的に追加しました。気まぐれに、私は 'の1つを複製しました。 jpg'ファイルを開き、その拡張子を '.jpeg'に変更しました。 '.jpeg'ファイルは正しく読み込まれますが、' .jpg'バージョンはまだダウンロードされます。正確に同じファイル。しかし、拡張子が.jpgのものはうまく動作します。興味深いもの: – espressoAndCode

+0

それは単に「https://storage.googleapis.com/bucketName/imageName.jpg」または「imageName」というURLを使用しています。ブラウザの "jpeg"? –

+0

これは正しいです。アップロード時にメタデータに 'inline'の値を明示的に追加した別のテストを実行しました。ストレージ内のすべてのファイルを削除して、応答オブジェクト*とCloud Storageコンソールは、mime-typeとdispositionが期待通りに設定されていることを確認しますが、今回はちょうど反対の動作をしています。ファイルはブラウザ内に表示され、 '.jpg'バージョンはダウンロードされます。Frustrating! – espressoAndCode

関連する問題