ExtJS 6 - 如何在不使用表单的情况下上传文件?

ExtJS 6 - How to upload a file without using form?

Ext JS 提供fileuploadfield,捆绑了一个浏览本地文件的按钮。我只需要在从本地选择文件后立即上传文件,而不是使用提交按钮来触发 post 过程。找不到选择文件后触发的事件。

p.s。实际上,我使用的版本是 Ext JS 6,但我认为基于以前版本的解决方案也可以。

您正在文件上传字段中查找事件 change

代码可能如下所示:

Ext.create('Ext.form.Panel', {
    renderTo: Ext.getBody(),
    title: 'Upload Panel',
    items: [{
        xtype: 'filefield',
        name: 'photo',
        fieldLabel: 'Photo',
        labelWidth: 50,
        msgTarget: 'side',
        allowBlank: false,
        anchor: '100%',
        buttonText: 'Select Photo...',
        listeners: {
            change: function (me, value, eOpts) {
                console.log('trigger upload of file:', value);
            }
        }
    }],
});

Fiddle https://fiddle.sencha.com/#view/editor&fiddle/1pd2

如果您想提交文件,您需要使用表格。即使您希望该按钮位于工具栏中,您也可以将其包含在一个表单中,它仍然看起来像一个普通的工具栏按钮(您需要为此指定正确的 ui 配置)。

示例:

dockedItems: [{
    dock: 'top',
    xtype: 'toolbar',
    items: [{
        xtype: 'form',
        padding: '10 0 0',
        url: 'submit/image',
        items: {
            xtype: 'filefield',
            buttonOnly: true,
            width: 100,
            buttonConfig: {
                text: 'Add logo',
                width: '100%',
                ui: 'default-toolbar-small'
            },
            listeners: {
                change: function (filefield) {
                    filefield.up('form').submit();
                }
            }
        }
    }, {
        text: 'Remove logo'
    }, '-', {
        text: 'Discard changes'
    }]
}]

工作 fiddle 示例:https://fiddle.sencha.com/#view/editor&fiddle/1pdk

虽然我同意 ,在您的情况下,在工具栏中嵌入表单可能是最简单的解决方案,但为了回答原始问题:

如果您真的不能或不想使用表单并且您不受浏览器支持的限制,请查看 FileReader

想法是在客户端 (JavaScript) 读取文件内容,然后使用常规 AJAX 请求发送数据。

您的代码可能如下所示:

function (fileField) {
    var file = fileField.fileInputEl.dom.files[0],
        reader;

    if (file === undefined || !(file instanceof File)) {
        return;
    }

    reader = new FileReader();    
    reader.onloadend = function (event) {
         var binaryString = '',
             bytes = new Uint8Array(event.target.result),
             length = bytes.byteLength,
             i,
             base64String;

         // convert to binary string
         for (i = 0; i < length; i++) {
             binaryString += String.fromCharCode(bytes[i]);
         }

         // convert to base64
         base64String = btoa(binaryString);

         Ext.Ajax.request({
             url: 'save-file.php',
             method: 'POST',
             params: {
                 data: base64String
             }
         });
    };

    reader.readAsArrayBuffer(file);
}

不需要表格。您可以使用 AJAX 和 FormData.

var file = s.fileInputEl.dom.files[0],
    data = new FormData();

data.append('file', file);

Ext.Ajax.request({
   url: '/upload/files',
   rawData: data,
   headers: {'Content-Type':null}, //to use content type of FormData
   success: function(response){ }
});

在线演示here