【问题标题】:Can't upload file from angular 5.2 to Laravel 5.5无法将文件从 angular 5.2 上传到 Laravel 5.5
【发布时间】:2018-05-06 02:47:19
【问题描述】:

尝试将文件从 Angular 5.2 上传到 Laravel 5.5 应用程序时,我遇到了一种奇怪的行为。文件数据在服务器端不可见/不可访问。

我尝试了不同的标题和方法,但它们似乎都失败了 -

HTML:

<input type="file" (change)="handleFileInput($event.target.files)" multiple/>

JS:

handleFileInput(files: FileList) {
        let formData = new FormData();
        formData.append('file', files[0], files[0].name);

        let headers = new HttpHeaders({
            'Content-Type': 'application/json' // also tried 'multipart/form-data' and undefined
        });
        const req = new HttpRequest('POST', 'https://uploader.test/upload', formData, {headers: headers});
        this.http.request(req).subscribe(res => console.log(res)); 
    }

在 Laravel 方面

logger('$request', [$request-&gt;all()]);

打印[]

还尝试了$request-&gt;file('file')Input::file('file'),它们都返回null。

浏览器的开发者工具显示以下负载已提交:

------WebKitFormBoundaryqZauUjRcPnD6wRmx
Content-Disposition: form-data; name="file"; filename="31562207_10106275826879542_6883202223082307584_n.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryqZauUjRcPnD6wRmx--

更新 控制器代码真的超级简单

 public function upload(Request $request)
    {
        logger('$request->all()', [$request->all()]);    // prints $request->all() [[]] []
        logger('Input::all()', [Input::all()]);    // prints Input::all() [[]] []
        logger('input.file', [ Input::file('file') ]);    // prints input.file [null] []
        logger('request.file', [ $request->file('file')]);    // prints request.file [null] []
        logger('$_POST', [$_POST]);    // prints $_POST [[]] []
        logger('$_FILES', [$_FILES]);    // prints $_FILES [[]] []
}

当我用一个对象替换 formData 时:

const req = new HttpRequest('POST', 'https://uploader.test/upload', {
            data: formData,
            file: files[0],
            test: '123'
        }, {headers: headers});
        this.http.request(req).subscribe(res => console.log(res));

我收到[{"data":[],"file":[],"test":"123"}]

我还尝试了以下解决方法(可在各种论坛中找到):

  • Laravel 解决方法 - formData.append('_method', 'PUT');
  • 使用http.post 代替http.request
  • 使用contentType: falseprocessData: false 添加选项
  • 已经尝试过其他问题中建议的解决方案,例如Angular-5 File Upload

在我的每一个测试中,文件数据本身都没有被传递到服务器。

任何帮助将不胜感激!

更新 2 - 请求标头的屏幕截图

【问题讨论】:

  • 从payload来看你应该是通过$request->file来获取文件的,你能在laravel端添加你的控制器代码吗?
  • 嗯,文件只能用multipart/form-data上传,这应该是你得到浏览器输出的原因,php/laravel应该是这样收到的,你能分享一些控制器代码吗?跨度>
  • @Hussein 更新了控制器代码,实际上只是尝试记录请求数据。
  • @Quezler 更新了控制器代码,它实际上只是尝试记录请求数据。当我手动设置multipart/form-data 时,出现“Missing boundary in multipart/form-data POST data”错误。
  • @Yani 你能显示请求发送的所有标头吗?通常边界是在标题中设置的,并且应该包含------WebKitFormBoundaryqZauUjRcPnD6wRmx 作为值

标签: angular laravel-5 file-upload angular5


【解决方案1】:

让我们试试这个:

对于 js 文件处理添加这个:

import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";

@Injectable()
export class FileUploader{
  constructor(public http:HttpClient){}

  handleFileInput(files: any){
    let xhr = new XMLHttpRequest();
    let form = new FormData();
    let token = "YOUR_TOKEN";
    form.append('file', files[0], files[0].name);
    xhr.onload = (e) =>{
      console.log('file uploaded');
    };
    xhr.open('POST', "https://uploader.test/upload", true);
    xhr.withCredentials = true;
    xhr.setRequestHeader('Authorization', 'Bearer ' + token);
    xhr.send(form);
  }
}

现在在 laravel 方面添加这个:

public function saveFile(Request $request){
   $path = $request->file('file')->store('uploaded');
   return response()-json($path);
}

在js代码中我使用了HttpClient,你可以使用XMLHttpRequest,试试看,如果不行请告诉我

【讨论】:

  • 我收到以下错误 - Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function store() on null。该文件没有通过。我删除了所有中间件只是为了确保仍然如此。
  • 好的,在你发送请求之前你能确保它在files的数组中吗?
  • 有 - 这是控制台日志打印的内容 - FileList {0: File(59965), length: 1} 0 : File(59965) {name: "tick_answered.jpeg", lastModified: 1525393170101, lastModifiedDate: Thu May 03 2018 17:19:30 GMT-0700 (PDT), webkitRelativePath: "", size: 59965, …} length : 1
  • 是的,这是可行的,但是它超出了角度范围,因此 http 拦截器将不会运行(负责添加 jwt 令牌和 api 密钥)。知道如何使用 http 服务来完成这项工作吗?
  • 我编辑了答案,你可以通过xhr.setRequestHeader设置任何你想要的标题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 2017-04-24
  • 2016-07-11
  • 2018-06-11
  • 2019-11-03
  • 2020-10-05
  • 2018-04-17
相关资源
最近更新 更多