【问题标题】:Laravel 5 TokenMismatchException on Multiple file uploadsLaravel 5 TokenMismatchException 上多个文件上传
【发布时间】:2015-09-30 00:06:48
【问题描述】:

在我的 Laravel 5 应用程序中,管理员可以上传产品图片和产品的 pdf 文件。因此,表单有 2 个输入字段,如下所示:

<div class="col-md-4 col-sm-6">
    <div class="form-group">
        {!! Form::label('image', 'Image File:') !!}
        {!! Form::file('image', ['class' => 'form-control input-sm'] ) !!}
    </div>
</div>

<div class="col-md-4 col-sm-6">
    <div class="form-group">
        {!! Form::label('leaflet', 'Leaflet:') !!}
        {!! Form::file('leaflet', ['class' => 'form-control input-sm'] ) !!}
    </div>
</div>

当我上传图片和传单都小于 2MB 时,上传成功。但是使用时,传单超过2MB,我得到TokenMismatchException at line 46

在我位于/etc/php5/apache2/php.iniphp.ini 文件中,我的配置如下:

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 2G

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 6G

我正在上传的文件(工作):

  1. 图片:名称:flower-1.jpg,尺寸:51.6kb
  2. PDF:名称:productInfo.pdf,大小:777.2kB

我上传的文件是(不工作 - 在 VerifyCsrfToken.php 的第 46 行给出 TokenMismatchException):

  1. 图片:名称:flower-1.jpg,尺寸:51.6kb
  2. PDF:名称:productInfo-1.pdf,大小:5.00MB

控制器

public function update( $id, UpdateProductRequest $request ) {
    $product = $this->prod->findProductById($id);

    $this->prod->updateProductOfId($product->id, $request);

    Flash::success('product_general_info_updated', 'The product general information has been successfully updated.');

    return redirect()->back();
}

/**
 * Coming from ProductRespository.php
 */
public function updateProductOfId($id, Request $request)
{
    $prd = $this->findProductById($id);

    $getAllInput = $request->all();

    if($request->file('image'))
    {
        $imageType = array(
            'product' => array(
                'height' => 347,
                'width' => 347
            ),
            'category' => array(
                'height' => 190,
                'width' => 190
            )
        );

        $imageFileName =  $request->file( 'image' )->getClientOriginalName();

        foreach ( $imageType as $key => $value )
        {
            $currentFile = Input::file( 'image' );
            $fileName = $currentFile->getClientOriginalName();
            $image = Image::make( $request->file( 'image' ) );
            $name = explode( '.', $fileName );
            $destinationPath = public_path().'/images/products/uploads';
            if ( $key === 'product' ) {
                $image->resize( $value[ 'width' ], $value[ 'height' ] );
                $image->save( $destinationPath . '/' . $name[ 0 ] . "-" . $value[ 'width' ] . "-" . $value[ 'height' ] . ".jpg", 100 );
            } elseif ( $key === 'category' ) {
                $image->resize( $value[ 'width' ], $value[ 'height' ] );
                $image->save( $destinationPath . '/' . $name[ 0 ] . "-" . $value[ 'width' ] . "-" . $value[ 'height' ] . ".jpg", 100 );
            }
        }
        $getAllInput['image'] = $imageFileName;
    }

    if($request->file('leaflet'))
    {
        $currentFile = Input::file( 'leaflet' );
        $fileName = $currentFile->getClientOriginalName();
        $destinationPath = public_path().'/leaflets/products/uploads';

        $currentFile->move($destinationPath, $fileName);
        $getAllInput['leaflet'] = $fileName;
    }
    return $prd->update($getAllInput);
}

编辑 1: 我使用的是Form Model Binding,所以createedit 文件的格式相同:

<div class="container">
    @include('errors.list')

    {!! Form::open(['url' => '/admin/products', 'autocomplete' => 'off', 'files' => true]) !!}
        @include('admin.products.product_general_form', ['submitButtonText' => 'Add Product'])
    {!! Form::close() !!}
</div>

编辑 2: 仅供参考,我在 Ubuntu 14.04 LTS x64 位架构上使用 LAMP。这是一个本地主机。我还没有托管应用程序。

请帮帮我。谢谢。

【问题讨论】:

  • 你能在你的视图中打开你的表单的地方添加你的代码吗?
  • 您是否使用Former 来处理您的表单?我无法理解您如何将文件上传至 2 MB,但仅此而已。你在这里使用什么网络服务器? (抱歉回复晚了)
  • 您是否尝试过类似ini_get('upload_max_filesize') 的方法来检查您的最大上传文件大小是否已由 conf 文件正确设置?
  • @YoannChambonnet 你可以查看我所做的更新。
  • 好的,你能试试我之前对ini_get的评论吗?

标签: php exception file-upload laravel-5


【解决方案1】:

我遇到了同样的问题,并且能够通过增加 UPLOAD_MAX_FILESIZE 和 POST_MAX_SIZE PHP 设置来解决它。前者应大于您上传的单个文件,后者应大于上传的两个(或更多)文件的总和。

对于这对 $_POST 变量的作用有更好的解释,这会导致此处显示为令牌不匹配异常:

http://laravel.io/forum/02-20-2014-l40-csrf-tokenmismatchexception-when-uploading-large-files

如果您还没有解决这个问题,希望这对您有用!

【讨论】:

  • POST_MAX_SIZE 是我的罪魁祸首。
【解决方案2】:

添加 {!! csrf_token() !!} 在您的表单中生成 CSRF 令牌。

{!! Form::open(['url' => '/admin/products', 'autocomplete' => 'off', 'files' => true]) !!} @include('admin.products.product_general_form', ['submitButtonText' => 'Add Product']) <input type="hidden" name="_token" value="{!! csrf_token() !!}"> {!! Form::close() !!}

目前在提交表单时,由于 VerifyCsrfToken.php 中间件,没有提供 Laravel 要求的 CSRF 令牌。

【讨论】:

  • 感谢您的意见先生,但我想请您再次阅读我的问题。因为我已经明确表示,小于 2MB 的文件会被上传,而比这更大,抛出 TokenMismatchException。仅供参考,HTML Form Facade 默认包含_token
  • 你的 php 配置中是否增加了 max_execution_time?
  • 为什么你认为我需要在我的 php 配置中增加 max_execution_time ?
  • 当您上传一个大文件时,脚本执行可能需要更多时间来处理上传整个文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2015-09-13
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 2016-03-06
相关资源
最近更新 更多