2017-12-02 25 views
8

Angular 4アプリからファイルコンテンツとしてBase64文字列を受け取るJSON APIサービスにファイルをアップロードしようとしています。Angular-upload file as base64

それでは、私がやっていることである - ユーザーがアップロードを確認したとき、私はAPIにJSONリクエストを作成し、私はそれ以前だファイルのbase64文字列を送信します、FileReader.readAsDataURLでファイルを読み込みます。

これは問題が始まるところである - とすぐに私は、「コンテンツ」と何かをして(W/E、それを送って、それをログ)要求は、例えば、送信が、そのめちゃくちゃスローされます2MBファイルの場合は20秒。

私が試してみました

  • ArrayBufferを使用して、手動でHTMLでbase64文字列を格納し、アップロードボタン
  • 上のユーザーがクリックした後、ファイルを読み込む
  • 後でそれを取得するbase64で
  • に変換します古いクライアントを使用する@angular/common
  • プレーンXHRリクエストを使用

しかし、すべてが同じ結果につながります。

私はどこに問題があるのか​​知っています。しかしなぜそれが起こるの?それは何かブラウザ特有のものか角に特有のものか?より好ましいアプローチがありますか(base64文字列でなければならないことに注意してください)?


注:APIで何も変更

  • APIは大丈夫です、私のコントロールを超えて、任意のファイルトラフ郵便配達を送信すると、すぐに

コードを終了します。

この方法は、ユーザーがドロップゾーンにファイルを追加したときに実行されます。

public onFileChange(files: File[]) : void { 
    files.forEach((file: File, index: number) => { 
     const reader = new FileReader; 

     // UploadedFile is just a simple model that contains filename, size, type and later base64 content 
     this.uploadedFiles[index] = new UploadedFile(file); 

     //region reader.onprogress 
     reader.onprogress = (event: ProgressEvent) => { 
      if (event.lengthComputable) { 
       this.uploadedFiles[index].updateProgress(
        Math.round((event.loaded * 100)/event.total) 
       ); 
      } 
     }; 
     //endregion 

     //region reader.onloadend 
     reader.onloadend = (event: ProgressEvent) => { 
      const target: FileReader = <FileReader>event.target; 
      const content = target.result.split(',')[1]; 

      this.uploadedFiles[index].contentLoaded(content); 
     }; 
     //endregion 

     reader.readAsDataURL(file); 
    }); 
} 

このメソッドは、ユーザーのクリックがサーバーに大きなファイルを送信するためのボタン

public upload(uploadedFiles: UploadedFile[]) : Observable<null> { 
    const body: object = { 
     files: uploadedFiles.map((uploadedFile) => { 
      return { 
       filename: uploadedFile.name, 
       // SLOWDOWN HAPPENS HERE 
       content: uploadedFile.content 
      }; 
     }) 
    }; 

    return this.http.post('file', body) 
} 
+0

コードの問題について質問していますが、コードを1行だけ転記しているわけではありません。 –

+0

@JB Nizet関連コードを追加しました – realshadow

+0

httpを使用するのではなく、単純な文字列連結を使用してJSON文字列を自分で作成した場合(base64にはエンコードされていない文字が含まれていないことがわかっているので) –

答えて

3

を保存するとき、あなたがそれを送ることができるようにFormDataを使用する必要があります実行します1つの大きなファイルの代わりに複数の部分として使用できます。以下のような

何か:

// import {Http, RequestOptions} from '@angular/http'; 
 
uploadFileToUrl(files, uploadUrl): Promise<any> { 
 
    // Note that setting a content-type header 
 
    // for mutlipart forms breaks some built in 
 
    // request parsers like multer in express. 
 
    const options = new RequestOptions(); 
 
    const formData = new FormData(); 
 

 
    // Append files to the virtual form. 
 
    for (const file of files) { 
 
    formData.append(file.name, file) 
 
    } 
 
    // Send it. 
 
    return this.http.post(uploadUrl, formData, options); 
 
    
 
}

はまた、私は時間のために、この上で、私の頭に傷き、ヘッダ'Content-Type': undefinedを設定することを忘れないでください。

+0

これは私のAPIを変更することができないので、私の問題は解決しません。私はこれが唯一の解決策であると考えているので、リクエストを処理するのに時間がかかる理由を探しています。とにかく – realshadow

+0

その場合、http圧縮/収縮@realshadowを使うことだけが念頭に置かれていることを覚えておいてください – Yaser