首页 > 解决方案 > 带有 CSV 文件的 CakePHP 4.x Ajax 请求

问题描述

我正在 CakePHP 4.x 中开发一个响应式用户界面,它偶尔会使用 Ajax 请求。我的 Ajax 请求执行得很好,但我在请求中合并 CSV 文件时遇到了很多麻烦,因此我的控制器可以处理数据。我想要完成的是我可以选择一个 CSV 文件,按提交,然后 Ajax 请求将文件发送到控制器并使用独立的行来更新数据库。

我的代码:

Javascript

function importProducts() {
    /* Getting form data */
    let form = document.getElementById('importProductsForm');

    let formData = new FormData();

    let file = $(form.products_file).prop('files')[0];

    formData.append("csv_file", file);

    /* Moving product stock */
    ajaxRequest('Products', 'importProducts', formData, processImportProducts);
}

function ajaxRequest(controller, action, data = null, callback = null) {
    $.ajax({
        url : "<?=$this->Url->build(['controller' => '']);?>" + "/" + controller + "/" + action,
        type : 'POST',
        data : {
            'data': data
        },
        dataType :'json',
        /*processData: false,*/
        /*contentType: false,*/
        success : function(dataArray) {    
            let response = dataArray.response;
            
            if (typeof response.data !== 'undefined') {
                data = response.data;
                
                if (callback != null) {
                    callback(data);
                }
            } else if (response.success == 0) {
                data = null;
                
                giveError(response.errorTemplate);
            } else {
                data = null;
                
                if (callback != null) {
                    callback(data);
                }
            }
        },
        error : function(request,error)
        {
            console.error(error);
        }
    });
}

目前,控制器功能除了接收和设置数据之外没有做任何特殊的事情:

public function importProducts() {
    $this->RequestHandler->renderAs($this, 'json');

    $response = [];

    if($this->request->is('post')) {
        $data = $this->request->getData();

        $response['test'] = $data;
    } else {
        $response['success'] = 0;
    }

    $this->set(compact('response'));
    $this->viewBuilder()->setOption('serialize', true);
    $this->RequestHandler->renderAs($this, 'json');
}

经过一番研究,我发现我可以使用 FormData 对象来发送文件。然后我收到的错误是“非法调用”。经过更多研究后,我发现这与 Ajax 的自动字符串解析有关。根据其他一些 StackOverflow 帖子,我可以通过将 processdata 和 contenttype 属性设置为 false 来解决这个问题。这解决了问题,但导致 Ajax 请求始终为空(不包含任何数据)。我在没有 CSV 文件的情况下使用包含字符串变量的常规数据对象对此进行了测试,但也导致了空请求(没有数据发送到控制器)。

所以我的问题是,如果没有 processdata 属性为 false,我会收到“非法调用”错误,否则如果 processdata 为 false,我的控制器中不会收到任何数据。我正在寻找解决此问题的解决方案,以便我可以将我的 CSV 文件或至少文件中的数据发送到我的控制器。

也欢迎使用 FormData 以外的其他解决方案,例如,我尝试在 Javascript 中读取 CSV 文件并将其转换为另一个对象(使用 jquery csv api)发送到控制器,遗憾的是直到现在都没有成功。

标签: javascriptjqueryajaxcsvcakephp-4.x

解决方案


推荐阅读