Techeek's Studio.

如何在小程序中上传下载文件

字数统计: 2.9k阅读时长: 11 min
2018/11/13

如何在小程序中实现文件上传下载

如何实现小程序登录鉴权这篇文章中,我们实现了小程序的wx.request请求操作,除了request之外,小程序还有文件下载wx.downloadFile和文件上传wx.uploadFile请求接口。那么这两个请求如何使用呢?请看本篇文章。

在教程开始之前,需要搭建搭建好小程序的基础开发环境,关于如何配置,大家可以参考如何入门小程序开发这篇文章的入门教程。

服务器配置

服务端的环境有很多选择NodeJS、PHP、Python等大部分主流语言都可以部署HTTP服务,今天我们将教大家使用PHP语言进行环境部署,其他语言请同学们自行部署。

我这里以Ubuntu Server 16.04 LTS为例,我们需要安装php运行环境及NginxWeb服务,同时也需要申请免费的SSL证书和域名,关于证书和域名的申请注册请参考如何快速搭建微信小程序这篇文章。注册完域名及证书申请,我们就可以开始部署服务器了!首先,登录服务器,执行下面的命令。

1
2
sudo apt update
sudo apt install php php-fpm php-curl nginx -y

安装完成后,使用浏览器访问你的服务器IP地址,如果看到下面的内容,则证明Web服务已经启动。

img

因为小程序获取远程数据,必须为HTTPS环境,所以目前搭建的环境,在小程序无法使用,接下来,我们将使用SSL证书加密小程序访问你服务器之间的流量。这里就需要刚才注册的域名及证书了。首先,将下载的证书,上传到你的服务器,并记录下这个位置。然后,我们将配置Nginx服务,以让其支持HTTPS流量。

我们找到/etc/nginx/conf.d文件夹,新建配置文件,为了方便后续修改,我将这里的配置文件修改为weixin.techeek.cn.conf大家可以根据自己的需求修改。

1
2
cd /etc/nginx/conf.d
sudo nano weixin.techeek.cn.conf

nano编辑器中,我们写下下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
listen 443 ssl;
server_name weixin.techeek.cn;
index index.php index.html index.htm;
root /usr/share/nginx/html;
ssl_certificate /home/ubuntu/1_weixin.techeek.cn_bundle.crt;
ssl_certificate_key /home/ubuntu/2_weixin.techeek.cn.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location ~ .php$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

server {
listen 80 default_server;
server_name weixin.techeek.cn;
root /usr/share/nginx/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}

一定注意,将文中server_name中的weixin.techeek.cn更换成你的域名。将ssl_certificatessl_certificate_key中证书的路径更换成你刚上传证书的路径。然后,执行下面的命令重启nginx服务。

1
sudo service nginx restart

之后,打开你电脑的浏览器,然后通过域名访问,注意,这里一定要在域名前加https://,比如我访问的域名https://weixin.techeek.cn

img

如果域名前有小锁标志,则证明你已经配置成功,可以开始下一步了。

下载

因为小程序要求必须使用自己的服务器进行文件上传下载,所以我们在开始之前必须搭建好服务器,否则无法使用小程序。

为了演示下载功能,你需要将一个文件上传到你的网页服务器的根目录,如果你按照我的教程,则这个目录是/usr/share/nginx/html/下,如图。

1542082862937

上传完成后,我们访问的部署的域名,即可查看到该文件,我这里访问的域名为https://weixin.techeek.cn/download.jpg。服务器端就准备完成了,我们可以开始准备小程序端的代码了。

小程序端

接下来,就可以在小程序端去下载这个文件了,打开index.wxml,撰写如下代码。

1
2
3
<button type="primary" bindtap="wx_download">下载</button>
<text>HTTP 状态码:{{statusCode}}</text>
<image src='{{filePath}}'></image>

这行代码中,我们使用下载按钮去触发wx_download函数,触发后函数自动返回statusCodefilePath的值在前端显示。接下来,我们修改index.js文件,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Page({
wx_download(){
var myThis = this;
wx.downloadFile({
url: 'https://weixin.techeek.cn/download.jpg', //请更改为你自己部署的接口
success(res) {
myThis.setData({
statusCode: res.statusCode
})
if (res.statusCode === 200) {
myThis.setData({
filePath: res.tempFilePath
})
}
}
})
},
})

当我们在前端点击下载按钮之后,调用wx.downloadFile去下载文件,但是这个wx.downloadFile函数到底是什么意思呢?我们先看看官方文档。

属性 类型 默认值 是否必填 说明
url string 下载资源的 url
header Object HTTP 请求的 Header,Header 中不能设置 Referer
filePath string 指定文件下载后存储的路径
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

object.success 回调函数

属性 类型 说明
tempFilePath string 临时文件路径。如果没传入 filePath 指定文件存储路径,则下载后的文件会存储到一个临时文件
statusCode number 开发者服务器返回的 HTTP 状态码

代码中,url为我们需要下载的文件,success为返回的事件,我们使用回调函数,判断当前下载的HTTP 状态码statusCode并在前端展示,如果这个状态码是200则将文件存储到tempFilePath的临时目录,之后在前端展示该文件,具体效果如图。

1542086713875

1542083049536

注:当点击下载按钮时,如果出现这种错误请登录小程序后台,点击设置-开发设置-服务器域名,将downloadFile改为你的服务器的域名。

除了回调函数,小程序也提供了一个返回值DownloadTask我们可以通过这个返回值函数来监控下载进度。代码如下。

index.wxml

1
2
3
4
5
6
7
<button type="primary" bindtap="wx_download">下载</button>
<view>
<progress percent="{{progress}}" active-mode="forwards" show-info active/>
<text>已下载:{{totalBytesWritten}}/{{totalBytesExpectedToWrite}}</text>
</view>
<text>HTTP 状态码:{{statusCode}}</text>
<video src='{{filePath}}'></video>

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Page({
wx_download(){
var myThis = this;
const downloadTask = wx.downloadFile({
url: 'https://weixin.techeek.cn/duck.mp4', //请更改为你自己部署的接口
success(res) {
myThis.setData({
statusCode: res.statusCode
})
if (res.statusCode === 200) {
myThis.setData({
filePath: res.tempFilePath
})
}
}
})
downloadTask.onProgressUpdate((res) => {
myThis.setData({
progress: res.progress,
totalBytesWritten: res.totalBytesWritten,
totalBytesExpectedToWrite: res.totalBytesExpectedToWrite
})
})
},
})

当我们下载视频时,就可以查看当前下载进度。

1542092497029

下载完成后,就可以播放视频了。

上传

在开始上传教程之前,我们需要配置好我们的服务器,否则无法进行本实验。

服务器配置

在第一步中,我们已经教大家部署了基本服务器,但是一直没用到PHP,接下来,将使用PHP代码来运行我们小程序的文件服务器。

运行

服务端已经配置完成,接下来我们就需要撰写服务端代码了,代码也很简单,我们需要将其放在/usr/share/nginx/html这个目录下,然后创建一个存放数据的upload文件夹,并赋予相关权限,使用下面的命令。

1
2
3
4
cd /usr/share/nginx/html
mkdir upload
sudo chmod 777 upload
sudo nano index.php

之后,使用nano编辑器撰写下面的代码。

1
2
3
4
<?php
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "/usr/share/nginx/html/upload/" . $_FILES["file"]["name"];
?>

然后按下键盘上的ctrl+X之后再按下Enter键,按Y即可保存。现在访问你的域名https://weixin.techeek.cn,看看其是否生效。

1542079319704

因为我们没传入文件,所以文件名部分是空的数据,没关系,能看到这步就证明你的服务器已经搭建完成。我们可以进行试验了!

小程序端

小程序端代码比较简单,通过几行代码即可实现,首先,我们修改index.wxml文件,代码如下。

1
2
<button type="primary" bindtap="wx_up">上传</button>
<text>HTTP 状态码:{{statusCode}}</text>

这段代码中,我们使用上传按钮执行wx_up函数,同时接受返回数据statusCode。接下来,我们修改index.js文件,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Page({
wx_up(){
var myThis = this;
wx.chooseImage({
success(res) {
const tempFilePaths = res.tempFilePaths
wx.uploadFile({
url: 'https://weixin.techeek.cn/', //请更改为你自己部署的接口
filePath: tempFilePaths[0],
name: 'file',
success(res) {
myThis.setData({
statusCode: res.statusCode
})
}
})
}
})
},
})

这段代码中,为了方便起见,我调用了wx.chooseImage去获取图片文件,并将其存储在临时目录,然后通过wx.uploadFile接口去上传图片文件到我们的服务器。过程比较简单,wx.chooseImage使用本文暂不介绍,我们来看看上传接口wx.uploadFile到底是什么意思,首先看看官方文档中的介绍。

属性 类型 默认值 是否必填 说明
url string 开发者服务器地址
filePath string 要上传文件资源的路径
name string 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容
header Object HTTP 请求 Header,Header 中不能设置 Referer
formData Object HTTP 请求中其他额外的 form data
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

object.success 回调函数

属性 类型 说明
data string 开发者服务器返回的数据
statusCode number 开发者服务器返回的 HTTP 状态码

在代码中,url为我们服务器的地址,填写的为https://weixin.techeek.cn/这里要更改为自己的接口,filePath为要上传文件资源的路径,我们这里写的是小程序图片的临时路径,wx.chooseImage接口的文件就暂存到这里。name为文件对应的key,我们填写的file即可。这是三个必填项,后续请求数据可以不填写。

接下来,需要在函数执行成功后,填写回调函数,这里,我们将返回的 HTTP 状态码通过setData方法,将数据存返回到前端。如果你看到如图的效果,证明文件上传完成。

1542081033746

接下来,看看服务器端是否有我们上传的图片文件。

1542081198137

我们看到,图片文件已近成功上传。

总结

那么,上传完成后,除了返回的statusCode,还有data参数,那么data参数如何使用?请关注本专栏,下篇文章,我们将讲解《如何在小程序中实现人脸识别功能》。

后续文章中我们将对这部分做详细介绍,并提供相关Demo做演示。喜欢的小伙伴请持续关注本专栏。腾讯云联合小程序给大家带来了小程序·云开发解决方案,为开发者提供完整的云端支持,弱化后端和运维操作,使用平台原生 API 进行核心业务开发,实现快速上线和迭代。欢迎免费使用!

CATALOG
  1. 1. 如何在小程序中实现文件上传下载
    1. 1.0.1. 服务器配置
  2. 1.1. 下载
    1. 1.1.1. 小程序端
  3. 1.2. 上传
    1. 1.2.1. 服务器配置
      1. 1.2.1.1. 运行
    2. 1.2.2. 小程序端
  4. 1.3. 总结