在 Yii2 中通过 Ajax 上传不包括文件 [英] Upload via Ajax in Yii2 not including files

查看:20
本文介绍了在 Yii2 中通过 Ajax 上传不包括文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 Ajax 请求上传图片,但似乎遇到了与 这个问题但它没有答案.我不确定它们是否完全相同,所以我会在此处发布所有我能找到的详细信息,希望更多详细信息可以帮助人们找到答案.

我正在从我的代码中解释以下内容(删除了很​​多我认为与此问题无关的内容),因此您看到的任何错别字都可能只是我更改了下面的代码.

以下内容包含在我的模型中:

use yii\web\UploadedFile;...类 Image 扩展 \yii\db\ActiveRecord{公共 $imageFile;公共函数规则(){返回 [[['imageFile'], 'file', 'skipOnEmpty' =>真的,扩展"=>'png, jpg'],];}公共函数上传(){如果 ($this->validate()) {$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName .'.' . $this->imageFile->extension);返回真;} 别的 {返回假;}}

这是我的视图文件的一部分:

 ['enctype' => 'multipart/form-data']]) ?><?= $form->field($model, 'title') ?><?= $form->field($model, 'imageFile')->fileInput() ?><?= Html::submitButton('上传', ['class' => 'btn btn-success']) ?><?php ActiveForm::end();?>

以及视图中的 Ajax

$('form').on('beforeSubmit', function(e) {var form = $(this);$.post(form.attr('action'), form.serialize()).done(function(result) {控制台日志(结果)});返回假;//防止默认表单提交动作});

我的控制器中的以下内容

use yii\web\UploadedFile;...公共函数 actionUpload(){$model = new Image();if (Yii::$app->request->isAjax) {$model->load(Yii::$app->request->post());$model->imageFile = UploadedFile::getInstance($model, 'imageFile');如果($模型->上传()){$model->save();//将标题保存到数据库Yii::$app->getSession()->addFlash('success', '图片上传');返回 $this->redirect(['index']);}}Yii::$app->response->format = Response::FORMAT_JSON;返回 ['返回' =>'只是我在这里测试'];}

上述 Ajax 只会将标题保存到数据库中,不会上传文件.如果我将所有内容都转换为标准发布请求,我就可以让它全部工作(标题保存到数据库,图像上传到正确的目录).如果我围绕各种视图、模型和控制器进行调试,看起来我只是没有通过 Ajax 请求获取 imageFile.$model->load(Yii::$app->request->post()); 加载通过 Ajax 提交的标题,那么为什么不拉文件?我想也许 $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles'); 将是提取 Ajax 提交文件的部分,但它似乎没有得到什么我也需要.作为测试,我什至尝试将 imageFile 属性视为纯文本并将其分配给另一个要写入的数据库属性,并且效果很好.所以它似乎被正确地包含在模型中,只是没有随 Ajax 提交一起发送.

谁能告诉我如何在 Yii2 中通过 Ajax 提交表单,包括选定的文件?

解决方案

问题

ajax 的问题是 $_FILES 详细信息没有在异步请求中发送.当我们在没有ajax请求的情况下提交填写好的表单并在PHP后端调试

echo '

';打印_r($_FILES);打印_r($_POST);echo '</pre>';死;

然后我们成功获取了 $_FILES$_POST 数据.

但是当我们在 ajax 请求中调试同样的东西时,我们只得到 $_POST 值,我们得到 $_FILES 作为 NULL.这使我们得出结论,$_FILES 数据不是通过我们的上述代码在 ajax 请求中发送的.

解决方案

我们需要使用FormData JavaScript.

它有什么作用?

简单来说就是把需要上传的文件的所有必要信息添加到$.ajax中的data参数中或者填写$_FILES 以及所有 $_POST 数据,即非文件输入,例如字符串数字等.

在您的视图文件中

 ['enctype' => 'multipart/form-data']]) ?><?= $form->field($model, 'title') ?><?= $form->field($model, 'imageFile')->fileInput() ?><button type="button" class="btn btn-success subm">上传</button><?php ActiveForm::end();?><脚本>$('.subm').click(function(e){var formData = new FormData($('form')[0]);控制台日志(表单数据);$.ajax({url: "some_php_file.php",//处理数据的服务器脚本类型:'POST',//表单数据数据:表单数据,beforeSend: beforeSendHandler,//它是一个你必须定义的函数成功:功能(响应){控制台日志(响应);},错误:函数(){alert('PHP 端出错!!');},//告诉jQuery不要处理数据或担心内容类型的选项.缓存:假,内容类型:假,过程数据:假});});

测试

现在通过 print_r() 在 PHP 代码中进行 ajax 请求和调试,如上所示,您会注意到 $_FILES 不是 NULL 并且它包含所有文件(其中需要上传)数据.如果设置了,您可以使用 move_uploaded_file() 功能

上传

这就是您的文件通过 Ajax 上传的方式.

参考 1

参考 2

参考 3

I'm trying to upload an image via Ajax request and seem to be hitting a similar issue as this question but it has no answer. I'm not sure if they are exactly the same so I'll post all the details I can here and hope the more detail helps someone find an answer.

I'm paraphrasing the below from my code (cutting out a lot of what I think is irrelevant to this question) so any typos you see are likely just me changing the code below.

The following is included in my model:

use yii\web\UploadedFile;

...

class Image extends \yii\db\ActiveRecord
{
    public $imageFile;

    public function rules()
    {
        return [
            [['imageFile'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
        ];
    }

    public function upload()
    {
        if ($this->validate()) {
            $this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
            return true;
        } else {
            return false;
        }
    }

Here is a portion of my view file:

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<?= Html::submitButton('Upload', ['class' => 'btn btn-success']) ?>
<?php ActiveForm::end(); ?>

And the Ajax in the view

$('form').on('beforeSubmit', function(e) {
    var form = $(this);
    $.post(form.attr('action'), form.serialize()).done(function(result) {
        console.log(result)
    });
    return false; // Prevent default form submit action
});

And the following in my controller

use yii\web\UploadedFile;

...

public function actionUpload()
{
    $model = new Image();

    if (Yii::$app->request->isAjax) {
        $model->load(Yii::$app->request->post());
        $model->imageFile = UploadedFile::getInstance($model, 'imageFile');
        if ($model->upload()) {
            $model->save(); // To save the title to the database
            Yii::$app->getSession()->addFlash('success', 'Image uploaded');
            return $this->redirect(['index']);
        }
    }

    Yii::$app->response->format = Response::FORMAT_JSON;
    return ['return' => 'just me testing here'];
}

The above Ajax will only ever save the title to the database and will not upload the file. If I transition everything to a standard post request I can get it all to work (title is saved to the database and image is uploaded to the proper directory). If I debug around the various views, models, and controllers, it looks like I'm just not getting the imageFile via the Ajax request. The $model->load(Yii::$app->request->post()); loads the title that was submitted via Ajax, so why does that not also pull the file? I thought maybe the $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles'); would be the part that pulls the Ajax submitted files but it doesn't seem to get what I need either. As a test, I even tried treating the imageFile property as plain text and assigning it to another database property to be written and it worked just fine. So it seems it's being included in the model properly, just not being send with the Ajax submit.

Can anyone tell me how, in Yii2, I can submit the form over Ajax, including the selected file?

解决方案

The Problem

What the problem in ajax is that $_FILES details are not sent in asynchroous request. When we submit the filled form without ajax request and debug in backend side in PHP by

echo '<pre>';
print_r($_FILES); 
print_r($_POST); 
echo '</pre>';
die; 

then we successfuly get $_FILES and $_POST data.

But when we debug the same thing in ajax request, we get only $_POST values and we get $_FILES as NULL. This led us to conclusion that $_FILES data are not sent in ajax request by our above code.

The Solution

We need to use FormData of JavaScript.

What does it do?

In simple words, it adds all necessary information of file which needs to be uploaded to data param in $.ajax OR fill up $_FILES as well as all $_POST data ie non file input such as strings number etc.

In your view file

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>    
<button type="button" class="btn btn-success subm">Upload</button>
<?php ActiveForm::end(); ?>

<script>
$('.subm').click(function(e){
    var formData = new FormData($('form')[0]);
    console.log(formData);
    $.ajax({
        url: "some_php_file.php",  //Server script to process data
        type: 'POST',

        // Form data
        data: formData,

        beforeSend: beforeSendHandler, // its a function which you have to define

        success: function(response) {
            console.log(response);
        },

        error: function(){
            alert('ERROR at PHP side!!');
        },


        //Options to tell jQuery not to process data or worry about content-type.
        cache: false,
        contentType: false,
        processData: false
    });
});
</script>

Testing

Now make ajax request and debug in PHP code by print_r() as shown above, you will notice that $_FILES is not NULL and its contains all file (which needs to be uploaded) data. And if it is set you can upload using move_uploaded_file() funtion

So this is how your file is uploaded via Ajax.

Referece 1

Referece 2

Referece 3

这篇关于在 Yii2 中通过 Ajax 上传不包括文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆