【问题标题】:File upload corruption文件上传损坏
【发布时间】:2020-09-27 03:03:01
【问题描述】:

我正在尝试将文件上传到共享点

  1. 仅使用 axios 的成功尝试如下

  2. 如果我使用 Guzzle 上传失败

最后上传的文件已损坏

【问题讨论】:

  • 你能补充更多细节吗?比如你上传方法的代码源以及文件是如何损坏的?
  • 文件源为 并且被 guzzle 客户端上传无法打开而损坏
  • 你能告诉我们你从这个请求中接受什么类型的文件吗?
  • Excel (.xlsx)、Word (.doc)
  • 不要使用图像/屏幕截图来发布您的代码。内联 markdown 代码块甚至支持语法高亮显示,您应该使用它们来发布您的代码。

标签: laravel axios guzzle


【解决方案1】:

您需要修改一些内容才能使其正常工作(已在我这边测试):

  1. 要获取文件的内容,你需要$request->file('file'),然后在上面使用file_get_contents()。您可能会丢失 get() 部分。

  2. 确保您发送的标头也接受multipart/form-data

    "Accept" => "multipart/form-data"
    
  3. 表单中的字段namefilename 是两个不同的东西。前者是字段名,后者是文件名。您需要同时发送两者。

试试这个:

protected function uploadFile(Request $request){
$file = $request->file('file');
$body = [
          "headers" => [
          "Accept" => "multipart/form-data",
          "Authorization" => "Bearer {$this->token}"
         ],
         "multipart" => [
          "name" => "file",
          "contents" => file_get_contents($file),
          "filename" => $file->getClientOriginalName()
        ]
     ];
return (new Client)->request('POST', 'https://.sharepoint.com/...', $body);
}

附言- 您可以使用isValid()检查文件是否有效:

if ($request->file('file')->isValid()) {
    //
}

官方文档:https://laravel.com/docs/7.x/requests#retrieving-uploaded-files

【讨论】:

    【解决方案2】:

    当提供内容以字符串形式上传到Guzzle客户端时, Guzzle 尝试推断有关文件的必要信息,例如 filenamecontent-type

    您可以通过在多部分负载中传递有关文件名和内容类型的信息来帮助Guzzle 正确推断这些信息以构建多部分请求。

    [
        //...
    
        'multipart' => [
            [
                'name' => 'fileName',
                'contents' => $request->file('file')->get(),
                'filename' => $request->file('file')->getName(),
                'headers' => [
                   'content-type' => $request->file('file')->getMimeType(),
                ]
            ]
        ]
    ]
    

    【讨论】:

    【解决方案3】:

    将内容类型添加为 blob。

    axios.post(
        'https://sharepoint....'
        ,data.get('file')
        {
            'headers' {
                'Authorization': `Bearer ${this.token}`
                ,'Content-Type': 'blob',
             }
        }
    )
    

    【讨论】:

    • OP 已请求 GuzzleHttp 的解决方案。内容是multipart/form-data 而不是blob
    【解决方案4】:

    试试这样的。 删除$request->file()->get()

    //Get the file object from the request.
    $file = $request->file('file');
    
    //Make the request
    return (new Client)->request('POST', 'https://.sharepoint.com/sites....', [
        'headers'      => [ 'Authorization' => "Bearer {$this->token}" ],
        'multipart' => [
            [
                'name'     => 'FileContents',
                'contents' => $file,
                'filename' => $file->getClientOriginalName()
            ],
            
        ],
    ]);
    

    【讨论】:

    • $file 是 UploadedFile 对象,所以它会上传一个对象而不是文件,但是 $file->get() 事件我得到损坏的文件
    【解决方案5】:

    在我看来,你应该先将它临时存储在本地服务器的某个地方,然后你将该文件发送到共享点,删除临时文件,我认为如果你不存储就立即发送,文件会损坏.请尝试以下方法

    $file = $request->file('logo');
    $original_name = $file->getClientOriginalName(); // get original file
    $name = time() . '_' . $original_name; // store it in different name so it would not be duplicated
    $path = base_path() .'/public_html/your_project/public/temporary/'; // full path of file folder
    // store the uploaded file
    $file->move($path, $name);
    $body = [
              "headers" => [
              "Authorization" => "Bearer {$this->token}"
             ],
             "multipart" => [
              "name" => "logo",
              "contents" => fopen($path . $name, 'r')
            ]
         ];
    $response = (new Client)->request('POST', 'https://.sharepoint.com/...', $body);
    // remove the file after done
    unlink($path . $name);
    return $response;
    

    希望这对你有用!如果我错了,请纠正我

    【讨论】:

    • 临时保存并按照您的建议发布,但没有帮助。还用这个临时文件尝试了其他解决方案:(
    • 对不起,您从 axios javacsript 发送到 php 时是否检查过文件是否损坏?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 2017-06-27
    相关资源
    最近更新 更多