上传

Quasar为您提供了一种通过QUploader组件上传文件的方法。

TIP

如果您只需要一个输入文件,您可能需要考虑使用QFile picker组件。

QUploader API

Loading API...

用法

WARNING

QUploader需要后端服务器来接收文件。 以下示例实际上不会上传。

TIP

QUploader兼容“拖放”。

WARNING

使用vee-validate时,必须重新命名vee-validate的“fieldBagName”配置,q-uploader才能正常工作。

设计

Basic



Dark



上传多个文件

默认情况下,将分别上传多个文件(每个文件一个线程)。 如果您希望所有文件都在一个线程中上传,请使用batch属性(在下面的示例中为第二个QUploader)。

Multiple



限制上传

Basic restrictions



TIP

在上面的示例中,我们使用了accept属性。 其值必须是用逗号分隔的唯一文件类型说明符列表。 对应到原生input type = file元素的’accept’属性。 更多信息

WARNING

accept属性的推荐格式为<mediatype>/<extension>。 示例:“image/jpeg”,“image/png”。 QUploader在幕后使用了<input type="file">,它完全依靠宿主浏览器来触发文件选择器。 如果accept属性(应用于input的属性)不正确,则屏幕上不会出现文件选择器,或者会出现但是它将接受所有文件类型。

您还可以应用自定义过滤器(在用户选择文件后执行):

Filter



添加头部

使用headers设置附加的XHR头部,以随上传请求一起发送。 如果需要嵌入其他字段,还请检查API中的form-fields属性。

Headers



TIP

这两个属性(headersform-fields)也可以用作函数((files) => Array),允许您根据要上传的文件动态设置它们。

还有一个with-credentials属性,它将上传过程使用的XHR的withCredentials设置为“true”。

处理上传

Auto upload on file selection



Custom upload URL



TIP

您也可以通过headersmethod属性自定义HTTP头部和HTTP方法。 检查QUploader API部分。

工厂函数

您可以使用一个factory属性,该属性必须是一个函数。 该函数可以返回一个对象或一个用对象解决的Promise(并且如果Promise失败,则会发出@factory-failed事件)。

上述对象可以覆盖以下QUploader属性:urlmethodheadersformFieldsfieldNamewithCredentialssendRaw。 这个对象的属性也可以是函数(形式为(file[s]) => value):

Promise-based factory function



您还可以使用factory函数属性并立即返回相同的对象。 如果要同时设置多个属性(如上所述),这将很有用:

Immediate return factory function



插槽

在下面的示例中,我们显示了等效于默认头部的内容。 还要注意一些可以使用的布尔scope属性:scope.canAddFilesscope.canUploadscope.isUploading

WARNING

请注意,您必须安装并使用另一个组件(QUploaderAddTrigger)才能将文件添加到队列中。 该组件需要放置在具有position: relative(提示:QBtn已经拥有)的DOM节点下,并且在用户单击其父元素时将自动注入必要的事件(请勿手动添加@click="scope.pickFiles")。如果触发器不工作,请检查是否在其上方渲染了元素,并相应地更改QUploaderAddTrigger的zIndex。

使用自定义头部以支持IE11

为了使用QBtn包裹QUPloaderAddTrigger时,文件选择器能在IE11上运行,请确保此按钮指定了type="a"

Custom header



Custom files list



服务器端例子

默认情况下,Quploader与HTTP(S)协议一起使用来上传文件(但不限于此,正如您将在此后面的部分中看到的那样)。

TIP

完全不需要像下面那样使用Nodejs服务器或Spring或ASP.NET-只要您使用的方法适合HTTP协议,就可以根据需要处理文件上传。 PHP的示例。

Nodejs

以下是用Node.js编写的基本服务器示例。 除了接收文件外,它什么也不做,因此请以它为起点。

const
  express = require('express'),
  app = express(),
  formidable = require('formidable'),
  path = require('path'),
  fs = require('fs'),
  throttle = require('express-throttle-bandwidth')

const
  port = process.env.PORT || 4444,
  folder = path.join(__dirname, 'files')

if (!fs.existsSync(folder)) {
  fs.mkdirSync(folder)
}

// 攻击者可以利用这个header来检测运行Express的应用程序,
// 然后发动专门的目标攻击
app.disable('x-powered-by')

app.set('port', port)
app.use(throttle(1024 * 128)) // 节流带宽

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
  next()
})

app.post('/upload', (req, res) => {
  const form = new formidable.IncomingForm()

  form.uploadDir = folder
  form.parse(req, (_, fields, files) => {
    console.log('\n-----------')
    console.log('Fields', fields)
    console.log('Received:', Object.keys(files))
    console.log()
    res.send('Thank you')
  })
})

app.listen(port, () => {
  console.log('\nUpload server running on http://localhost:' + port)
})

ASP.NET MVC/Core

QUploader与Microsoft ASP.NET MVC/Core 2.x Web API后端无缝集成。 在您的Vue文件中,为QUploader组件配置所需的Web API端点:

<q-uploader
  url="http://localhost:4444/fileuploader/upload"
  label="Upload"
  style="max-width: 300px"
/>

如果您的服务器需要JWT令牌之类的身份验证,请使用QUploader的工厂函数指定QUploader将使用的xhr头部。 例如:

<template>
  <q-uploader
    label="Upload"
    :factory="factoryFn"
    style="max-width: 300px"
  />
</template>

<script>
export default {
  methods: {
    factoryFn (file) {
      return new Promise((resolve, reject) => {
        // 从您的存储中检索JWT令牌。
        const token = "myToken";
        resolve({
          url: 'http://localhost:4444/fileuploader/upload',
          method: 'POST',
          headers: [
            { name: 'Authorization', value: `Bearer ${token}` }
          ]
        })
      })
    }
  }
}
</script>

QUploader的文件有效载荷将是格式正确的IFormFileCollection对象,您可以通过ASP.NET Web API控制器的.Request属性读取该对象。 ASP.NET Core 2.2控制器:

[Route("api/[controller]")]
[ApiController]
public class FileUploaderController : ControllerBase
{
    [HttpPost]
    public async Task upload()
    {
        // 请求的.Form.Files属性
        // 将包含QUploader的文件。
        var files = this.Request.Form.Files;
        foreach (var file in files)
        {
            if (file == null || file.Length == 0)
                continue;

            // 对文件进行处理。
            var fileName = file.FileName;
            var fileSize = file.Length;
            // 保存到服务器...
            // ...
        }
    }
}

Spring

以下是Spring示例。 属性fieldName="file"@RequestPart(value = "file")映射。

// java
@RestController
public class UploadRest {
	@PostMapping("/upload")
	public void handleFileUpload(@RequestPart(value = "file") final MultipartFile uploadfile) throws IOException {
		saveUploadedFiles(uploadfile);
	}

	private String saveUploadedFiles(final MultipartFile file) throws IOException {
		final byte[] bytes = file.getBytes();
		final Path path = Paths.get("YOUR_ABSOLUTE_PATH" + file.getOriginalFilename());
		Files.write(path, bytes);
	}
}

// html
<q-uploader field-name="file" url="YOUR_URL_BACK/upload" with-credentials />

Python/Flask

// python
from flask import Flask, request
from werkzeug import secure_filename
from flask_cors import CORS
import os

app = Flask(__name__)

# This is necessary because QUploader uses an AJAX request
# to send the file
cors = CORS()
cors.init_app(app, resource={r"/api/*": {"origins": "*"}})

@app.route('/upload', methods=['POST'])
def upload():
    for fname in request.files:
        f = request.files.get(fname)
        print(f)
        f.save('./uploads/%s' % secure_filename(fname))

    return 'Okay!'

if __name__ == '__main__':
    if not os.path.exists('./uploads'):
        os.mkdir('./uploads')
    app.run(debug=True)

支持其他服务

QUploader当前支持通过HTTP协议上载。 但是您也可以扩展该组件以支持其他服务。 例如Firebase。 告诉你如何做到。

以下是您需要提供的API的示例。 您将创建一个扩展QUploader基础的新的Vue组件,然后可以将其导入并在您的网站/应用中使用。

基本上,QUploader是QUploaderBase + xhr混入(mixin)。你的组件将是QUploaderBase + 你的服务混入(mixin)。

TIP

对于默认的XHR实现,请查看源代码

乐意接受帮助

我们也很乐意接受支持其他上传服务的PR,因此其他人可以从中受益。

对于UMD版本,您可以扩展Quasar.components.QUploaderBase

// MyUploader.js
import { QUploaderBase } from 'quasar'

export default {
  name: 'MyUploader',

  mixins: [ QUploaderBase ],

  computed: {
    // [必需]
    // 我们正在上传文件
    isUploading () {
      // 返回<Boolean>
    },

    // [可选]
    // 显示上传器顶部的覆盖层,
    // 表明它正在等待某件事
    // (阻止所有控件)
    isBusy () {
      // 返回<Boolean>
    }
  },

  methods: {
    // [必需]
    // 中止并清理
    // 正在进行的任何进程
    abort () {
      // ...
    },

    // [必需]
    upload () {
      if (this.canUpload === false) {
        return
      }

      // ...
    }
  }
}

然后在Vue中全局注册此组件,或者导入它并将其添加到Vue组件中的“components:{}”。

// globally registering your component
import Vue from 'vue'
import MyUploader from '../../path/to/MyUploader' // the file from above
Vue.component('MyUploader', MyUploader)

// or declaring it in a .vue file
import MyUploader from '../../path/to/MyUploader' // the file from above
export default {
  // ...
  components: {
    // ...
    MyUploader
  }
}