整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

使用Vue实现图片上传的三种方式

目中需要上传图片可谓是经常遇到的需求,本文将介绍 3 种不同的图片上传方式,在这总结分享一下,有什么建议或者意见,请大家踊跃提出来。

没有业务场景的功能都是耍流氓,那么我们先来模拟一个需要实现的业务场景。假设我们要做一个后台系统添加商品的页面,有一些商品名称、信息等字段,还有需要上传商品轮播图的需求。

我们就以Vue、Element-ui,封装组件为例子聊聊如何实现这个功能。其他框架或者不用框架实现的思路都差不多,本文主要聊聊实现思路。

1.云储存

常见的 七牛云,OSS(阿里云)等,这些云平台提供API接口,调用相应的接口,文件上传后会返回图片存储在服务器上的路径,前端获得这个路径保存下来提交给后端即可。此流程处理相对简单。

主要步骤

  • 向后端发送请求,获取OSS配置数据
  • 文件上传,调用OSS提供接口
  • 文件上传完成,后的文件存储在服务器上的路径
  • 将返回的路径存值到表单对象中

代码范例

我们以阿里的 OSS 服务来实现,们试着来封装一个OSS的图片上传组件。

通过element-ui的upLoad组件的 http-request 参数来自定义我们的文件上传,仅仅使用他组件的样式,和其他上传前的相关钩子(控制图片大小,上传数量限制等)。

<template>
 <el-upload
 list-type="picture-card"
 action="''"
 :http-request="upload"
 :before-upload="beforeAvatarUpload">
 <i class="el-icon-plus"></i>
 </el-upload>
</template>
 
<script>
 import {getAliOSSCreds} from '@/api/common' // 向后端获取 OSS秘钥信息
 import {createId} from '@/utils' // 一个生产唯一的id的方法
 import OSS from 'ali-oss'
 
 export default {
 name: 'imgUpload',
 data () {
 return {}
 },
 methods: {
 // 图片上传前验证
 beforeAvatarUpload (file) {
 const isLt2M = file.size / 1024 / 1024 < 2
 if (!isLt2M) {
 this.$message.error('上传头像图片大小不能超过 2MB!')
 }
 return isLt2M
 },
 // 上传图片到OSS 同时派发一个事件给父组件监听
 upload (item) {
 getAliOSSCreds().then(res => { // 向后台发请求 拉取OSS相关配置
 let creds = res.body.data
 let client = new OSS.Wrapper({
 region: 'oss-cn-beijing', // 服务器集群地区
 accessKeyId: creds.accessKeyId, // OSS帐号
 accessKeySecret: creds.accessKeySecret, // OSS 密码
 stsToken: creds.securityToken, // 签名token
 bucket: 'imgXXXX' // 阿里云上存储的 Bucket
 })
 let key = 'resource/' + localStorage.userId + '/images/' + createId() + '.jpg' // 存储路径,并且给图片改成唯一名字
 return client.put(key, item.file) // OSS上传
 }).then(res => {
 console.log(res.url)
 this.$emit('on-success', res.url) // 返回图片的存储路径
 }).catch(err => {
 console.log(err)
 })
 }
 }
 }
</script>

传统文件服务器上传图片

此方法就是上传到自己文件服务器硬盘上,或者云主机的硬盘上,都是通过 formdata 的方式进行文件上传。具体的思路和云文件服务器差不多。

主要步骤

  • 设置服务器上传路径、上传文件字段名、header、data参数等
  • 上传成功后,返回服务器存储的路径
  • 返回的图片路径存储到表单提交对象中

代码示例

此种图片上传根据element-ui的upLoad组件只要传入后端约定的相关字段即可实现,若使用元素js也是生成formdata对象,通过Ajax去实现上传也是类似的。

这里只做一个简单的示例,具体请看el-upload组件相文档就能实现

<template>
 <el-upload
 ref="imgUpload"
 :on-success="imgSuccess"
 :on-remove="imgRemove"
 accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"
 :headers="headerMsg"
 :action="upLoadUrl"
 multiple>
 <el-button type="primary">上传图片</el-button>
 </el-upload>
</template>
 
<script>
 import {getAliOSSCreds} from '@/api/common' // 向后端获取 OSS秘钥信息
 import {createId} from '@/utils' // 一个生产唯一的id的方法
 import OSS from 'ali-oss'
 
 export default {
 name: 'imgUpload',
 data () {
 return {
 headerMsg:{Token:'XXXXXX'},
 upLoadUrl:'xxxxxxxxxx'
 }
 },
 methods: {
 // 上传图片成功
 imgSuccess (res, file, fileList) {
 console.log(res)
 console.log(file)
 console.log(fileList) // 这里可以获得上传成功的相关信息
 }
 }
 }
</script>

图片转 base64 后上传

有时候做一些私活项目,或者一些小图片上传可能会采取前端转base64后成为字符串上传。当我们有这一个需求,有一个商品轮播图多张,转base64编码后去掉data:image/jpeg;base64,将字符串以逗号的形势拼接,传给后端。我们如何来实现呢。

1.本地文件如何转成 base64

我们通过H5新特性 readAsDataURL 可以将文件转base64格式,轮播图有多张,可以在点击后立马转base64也可,我是在提交整个表单钱一次进行转码加工。

具体步骤

  • 新建文件封装 异步 转base64的方法
  • 添加商品的时候选择本地文件,选中用对象保存整个file对象
  • 最后提交整个商品表单之前进行编码处理

在这里要注意一下,因为 readAsDataURL 操作是异步的,我们如何将存在数组中的若干的 file对象,进行编码,并且按照上传的顺序,把编码后端图片base64字符串储存在一个新数组内呢,首先想到的是promise的链式调用,可是不能并发进行转码,有点浪费时间。我们可以通过循环 async 函数进行并发,并且排列顺序。请看 methods 的 submitData 方法

utils.js

export function uploadImgToBase64 (file) {
 return new Promise((resolve, reject) => {
 const reader = new FileReader()
 reader.readAsDataURL(file)
 reader.onload = function () { // 图片转base64完成后返回reader对象
 resolve(reader)
 }
 reader.onerror = reject
 })
}

添加商品页面 部分代码

<template>
 <div>
 <el-upload
 ref="imgBroadcastUpload"
 :auto-upload="false" multiple
 :file-list="diaLogForm.imgBroadcastList"
 list-type="picture-card"
 :on-change="imgBroadcastChange"
 :on-remove="imgBroadcastRemove"
 accept="image/jpg,image/png,image/jpeg"
 action="">
 <i class="el-icon-plus"></i>
 <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过2M</div>
 </el-upload>
 <el-button>submitData</el-button> 
 </div>
</template>
 
<script>
 import { uploadImgToBase64 } from '@/utils' // 导入本地图片转base64的方法
 
 export default {
 name: 'imgUpload',
 data () {
 return {
 diaLogForm: {
 goodsName:'', // 商品名称字段
 imgBroadcastList:[], // 储存选中的图片列表
 imgsStr:'' // 后端需要的多张图base64字符串 , 分割
 }
 }
 },
 methods: {
 // 图片选择后 保存在 diaLogForm.imgBroadcastList 对象中
 imgBroadcastChange (file, fileList) {
 const isLt2M = file.size / 1024 / 1024 < 2 // 上传头像图片大小不能超过 2MB
 if (!isLt2M) {
 this.diaLogForm.imgBroadcastList = fileList.filter(v => v.uid !== file.uid)
 this.$message.error('图片选择失败,每张图片大小不能超过 2MB,请重新选择!')
 } else {
 this.diaLogForm.imgBroadcastList.push(file)
 }
 },
 // 有图片移除后 触发
 imgBroadcastRemove (file, fileList) {
 this.diaLogForm.imgBroadcastList = fileList
 },
 // 提交弹窗数据
 async submitDialogData () {
 const imgBroadcastListBase64 = []
 console.log('图片转base64开始...')
 // 并发 转码轮播图片list => base64
 const filePromises = this.diaLogForm.imgBroadcastList.map(async file => {
 const response = await uploadImgToBase64(file.raw)
 return response.result.replace(/.*;base64,/, '') // 去掉data:image/jpeg;base64,
 })
 // 按次序输出 base64图片
 for (const textPromise of filePromises) {
 imgBroadcastListBase64.push(await textPromise)
 }
 console.log('图片转base64结束..., ', imgBroadcastListBase64)
 this.diaLogForm.imgsStr = imgBroadcastListBase64.join()
 console.log(this.diaLogForm)
 const res = await addCommodity(this.diaLogForm) // 发请求提交表单
 if (res.status) {
 this.$message.success('添加商品成功')
 // 一般提交成功后后端会处理,在需要展示商品地方会返回一个图片路径 
 }
 },
 }
 }
</script>

这样本地图片上传的时候转base64上传就完成了。可是轮播图有可以进行编辑,我们该如何处理呢?一般来说商品增加页面和修改页面可以公用一个组件,那么我们继续在这个页面上修改。

编辑时我们首先会拉取商品原有数据,进行展示,在进行修改,这时候服务器返回的图片是一个路径 http://xxx.xxx.xxx/abc.jpg 这样,当我们新增一张图片的还是和上面的方法一样转码即可。可是后端说,没有修改的图片也要赚base64转过来,好吧那就做把。这是一个在线链接 图片,不是本地图片,怎么做呢?

2. 在线图片转base64

具体步骤

utils.js 文件添加在线图片转base64的方法,利用canvas

编辑商品,先拉取原来的商品信息展示到页面

提交表单之前,区分在线图片还是本地图片进行转码

utils.js

export function uploadImgToBase64 (file) {
 return new Promise((resolve, reject) => {
 function getBase64Image (img) {
 const canvas = document.createElement('canvas')
 canvas.width = img.width
 canvas.height = img.height
 const ctx = canvas.getContext('2d')
 ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
 var dataURL = canvas.toDataURL()
 return dataURL
 }
 
 const image = new Image()
 image.crossOrigin = '*' // 允许跨域图片
 image.src = img + '?v=' + Math.random() // 清除图片缓存
 console.log(img)
 image.onload = function () {
 resolve(getBase64Image(image))
 }
 image.onerror = reject
 })
}

添加商品页面 部分代码

<template>
 <div>
 <el-upload
 ref="imgBroadcastUpload"
 :auto-upload="false" multiple
 :file-list="diaLogForm.imgBroadcastList"
 list-type="picture-card"
 :on-change="imgBroadcastChange"
 :on-remove="imgBroadcastRemove"
 accept="image/jpg,image/png,image/jpeg"
 action="">
 <i class="el-icon-plus"></i>
 <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过2M</div>
 </el-upload>
 <el-button>submitData</el-button> 
 </div>
</template>
 
<script>
 import { uploadImgToBase64, URLImgToBase64 } from '@/utils'
 
 export default {
 name: 'imgUpload',
 data () {
 return {
 diaLogForm: {
 goodsName:'', // 商品名称字段
 imgBroadcastList:[], // 储存选中的图片列表
 imgsStr:'' // 后端需要的多张图base64字符串 , 分割
 }
 }
 },
 created(){
 this.getGoodsData()
 },
 methods: {
 // 图片选择后 保存在 diaLogForm.imgBroadcastList 对象中
 imgBroadcastChange (file, fileList) {
 const isLt2M = file.size / 1024 / 1024 < 2 // 上传头像图片大小不能超过 2MB
 if (!isLt2M) {
 this.diaLogForm.imgBroadcastList = fileList.filter(v => v.uid !== file.uid)
 this.$message.error('图片选择失败,每张图片大小不能超过 2MB,请重新选择!')
 } else {
 this.diaLogForm.imgBroadcastList.push(file)
 }
 },
 // 有图片移除后 触发
 imgBroadcastRemove (file, fileList) {
 this.diaLogForm.imgBroadcastList = fileList
 },
 // 获取商品原有信息
 getGoodsData () {
 getCommodityById({ cid: this.diaLogForm.id }).then(res => {
 if (res.status) {
 Object.assign(this.diaLogForm, res.data)
 // 把 '1.jpg,2.jpg,3.jpg' 转成[{url:'http://xxx.xxx.xx/j.jpg',...}] 这种格式在upload组件内展示。 imgBroadcastList 展示原有的图片
 this.diaLogForm.imgBroadcastList = this.diaLogForm.imgsStr.split(',').map(v => ({ url: this.BASE_URL + '/' + v })) 
 }
 }).catch(err => {
 console.log(err.data)
 })
 },
 // 提交弹窗数据
 async submitDialogData () {
 const imgBroadcastListBase64 = []
 console.log('图片转base64开始...')
 this.dialogFormLoading = true
 // 并发 转码轮播图片list => base64
 const filePromises = this.diaLogForm.imgBroadcastList.map(async file => {
 if (file.raw) { // 如果是本地文件
 const response = await uploadImgToBase64(file.raw)
 return response.result.replace(/.*;base64,/, '')
 } else { // 如果是在线文件
 const response = await URLImgToBase64(file.url)
 return response.replace(/.*;base64,/, '')
 }
 })
 // 按次序输出 base64图片
 for (const textPromise of filePromises) {
 imgBroadcastListBase64.push(await textPromise)
 }
 console.log('图片转base64结束...')
 this.diaLogForm.imgs = imgBroadcastListBase64.join()
 console.log(this.diaLogForm)
 if (!this.isEdit) { // 新增编辑 公用一个组件。区分接口调用
 const res = await addCommodity(this.diaLogForm) // 提交表单
 if (res.status) {
 this.$message.success('添加成功')
 }
 } else {
 const res = await modifyCommodity(this.diaLogForm) // 提交表单
 if (res.status) {
 this.$router.push('/goods/goods-list')
 this.$message.success('编辑成功')
 }
 }
 }
 }
 }
</script>

结语

至此常用的三种图片上传方式就介绍完了,转base64方式一般在小型项目中使用,大文件上传还是传统的 formdata或者 云服务,更合适。但是 通过转base64方式也使得,在前端进行图片编辑成为了可能,不需要上传到服务器就能预览。主要收获还是对于异步操作的处理。

最后

以下是总结出来最全前端框架视频,包含: javascript/vue/react/angualrde/express/koa/webpack 等学习资料。

【领取方式】

关注头条 前端全栈架构丶第一时间获取最新前端资讯学习

手机用户可私信关键词 【前端】即可获取全栈工程师路线和学习资料!

.需求

最近我们公司在做一个官网涉及到图片视频上传的问题,时间比较紧急(实际后端想偷懒),就让我直传视频到阿里云的oss上。我一听,也是一脸懵,人在家中坐,锅从天上来。话不多说,我直冲度娘,网上的案例真的是非常的多,眼花缭乱,我也试了几个发现都是有问题的,又联系不到博主,最终我还是放弃了,干脆自己搞一个吧,经过三天三夜的奋战(其实是一晚上)!所以分享出来给各位小伙伴们,希望早日脱坑!

先上效果图


2.阿里oss的安装

npm install ali-oss --save

3.封装oss通用上传js工具类

 "use strict";
import { dateFormat } from './utils.js'

var OSS = require("ali-oss");
let url='';

export default {
  /**
   * 创建随机字符串
   * @param num
   * @returns {string}
   */
  randomString(num) {
    const chars = [
      "0",
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z"
    ];
    let res = "";
    for (let i = 0; i < num; i++) {
      var id = Math.ceil(Math.random() * 35);
      res += chars[id];
    }
    return res;
  },

  /**
   * 创建oss客户端对象
   * @returns {*}
   */
  createOssClient() {
    return new Promise((resolve, reject) => {
      const client = new OSS({
        region: "XXXXX", // 请设置成你的
        accessKeyId: "XXXXX", // 请设置成你的
        accessKeySecret: "XXXXX", // 请设置成你的
        bucket: "XXXXX", // 请设置成你的
        secure: true // 上传链接返回支持https
      });
      resolve(client);
    });
  },
  /**
   * 文件上传
   * @param option 参考csdn: https://blog.csdn.net/qq_27626333/article/details/81463139
   */
  ossUploadFile(option) {
    const file = option.file;
    const self = this;
	// var url = '';
    return new Promise((resolve, reject) => {
      const date = dateFormat(new Date(), "yyyyMMdd"); // 当前时间
      const dateTime = dateFormat(new Date(), "yyyyMMddhhmmss"); // 当前时间
      const randomStr = self.randomString(4); //  4位随机字符串
      const extensionName = file.name.substr(file.name.indexOf(".")); // 文件扩展名
      const fileName =
        "video/" + date + "/" + dateTime + "_" + randomStr + extensionName; // 文件名字(相对于根目录的路径 + 文件名)
      // 执行上传
      self.createOssClient().then(client => {
        // 异步上传,返回数据
        resolve({
          fileName: file.name,
          fileUrl: fileName
        });
        // 上传处理
        // 分片上传文件
        client
          .multipartUpload(fileName, file, {
            progress: function(p) {
              const e = {};
              e.percent = Math.floor(p * 100);
              // console.log('Progress: ' + p)
              option.onProgress(e);
            }
          })
          .then(
            val => {
			  window.url = val
              console.info('woc',url);
              if (val.res.statusCode === 200) {
                option.onSuccess(val);
                return val;
              } else {
                option.onError("上传失败");
              }
            },
            err => {
              option.onError("上传失败");
              reject(err);
            }
          );
      });
    });
  }
};

4.在src下的util文件创建utils.js工具类

 /**
 * 时间日期格式化
 * @param format
 * @returns {*}
 */
export const dateFormat = function(dateObj, format) {
  const date = {
    "M+": dateObj.getMonth() + 1,
    "d+": dateObj.getDate(),
    "h+": dateObj.getHours(),
    "m+": dateObj.getMinutes(),
    "s+": dateObj.getSeconds(),
    "q+": Math.floor((dateObj.getMonth() + 3) / 3),
    "S+": dateObj.getMilliseconds()
  };
  if (/(y+)/i.test(format)) {
    format = format.replace(
      RegExp.$1,
      (dateObj.getFullYear() + "").substr(4 - RegExp.$1.length)
    );
  }
  for (const k in date) {
    if (new RegExp("(" + k + ")").test(format)) {
      format = format.replace(
        RegExp.$1,
        RegExp.$1.length === 1
          ? date[k]
          : ("00" + date[k]).substr(("" + date[k]).length)
      );
    }
  }
  return format;
};

5.vue页面中的使用

<template>
    <div>
            <el-form :model="form" label-width="80px" size="small">
                <el-form-item label="上传视频">
                    <el-upload  class="upload-demo" action=""
                               :http-request="fnUploadRequest"
                               :show-file-list="true"
                               :limit=1
                               :on-exceed="beyondFile"
                               :on-success="handleVideoSuccess"
                               :before-upload="beforeUploadVideo">
                        <div tabindex="0" class="el-upload-video">
                            <i class="el-upload-video-i el-icon-plus avatar-uploader-icon"></i>
                        </div>
                        <div class="el-upload__tip" slot="tip">上传视频文件,且不超过500mb</div>
                    </el-upload>
					 <el-input type="textarea" rows="5" v-model="urls"></el-input>
                </el-form-item>
            </el-form>
    </div>
</template>

6.js中的代码

 <script>
  import oss from '../../util/oss.js'
 
  export default {
    data: function() {
      return {
        form: {
          status: true
        },
		url:[],
		urls:''
      }
    },
    methods: {
      /**
       * @description [fnUploadRequest 覆盖默认的上传行为,实现自定义上传]
       * @param    {object}   option [上传选项]
       * @return   {null}   [没有返回]
       */
      async fnUploadRequest(option) {
        oss.ossUploadFile(option);
      },
      // 视频上传
      beforeUploadVideo(file) {
        // todo
      },
      // 视频上传成功后
      handleVideoSuccess(response, file, fileList) {
		 console.log('url',window.url);
		  console.log('url',window.url.res.requestUrls);
		 this.url = window.url.res.requestUrls;
		 console.log('3322',this.url.length)
		  for(var i = 0;i<this.url.length;i++){
			  console.log('href',this.url[i])
			  this.urls = this.url[i].split('?')[0]
			  console.log('jjjj',this.url)
		  }
        // todo
      },
      // 视频添加多个视频文件事件
      beyondFile(files, fileList) {
      },
    }
  }
</script>

7.css代码

<style lang="less" scoped>
    .el-upload-video {
        width: 100px;
        height: 100px;
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }
    .el-upload-video-i{
        font-size: 36px;
        padding-top: 25px;
        color: #8c939d;
        width: 50px;
        height: 50px;
        line-height: 50px;
        text-align: center;
    }
</style>

8.总结

我在这里讲一下需要注意的几点:

1.这个我没有贴出阿里云的一些配置,自己可以问问度娘,网上有很多资料,注意跨域的配置就行。

2.这样做的优点就是不用和后端交互,图片直传到你阿里云的oss然后返回链接,不需要后端的传值,省去了很多和后端人员联调的时间,大大提高了开发的效率。

代码我已经都贴出来了,样式的话可以自己改,这个是可以根据自己的需求来更改的,如果还有什么问题的话,欢迎留言评论!


图片来源于网络

是一个包含了函数计算每种 Runtime 结合 HTTP Trigger 实现文件上传和文件下载的示例集。每个示例包括:

  • 一个公共 HTML 页面,该页面有一个文件选择框和上传按钮,会列出已经上传的文件,点击某个已上传的文件可以把文件下载下来;
  • 支持文件上传、下载和列举的函数。

我们知道不同语言在处理 HTTP 协议上传下载时都有很多中方法和社区库,特别是结合函数计算的场景,开发人员往往需要耗费不少精力去学习和尝试。本示例集编撰的目的就是节省开发者甄别的精力和时间,为每种语言提供一种有效且符合社区最佳实践的方法,可以拿来即用。

当前已支持的 Runtime 包括:

  • nodejs
  • python
  • php
  • java

计划支持的 Runtime 包括:

  • dotnetcore

不打算支持的 Runtime 包括:

  • custom

使用限制

由于函数计算对于 HTTP 的 Request 和 Response 的 Body 大小限制均为 6M,所以该示例集只适用于借助函数计算上传和下载文件小于 6M 的场景。对于大于 6M 的情况,可以考虑如下方法:

  1. 分片上传,把文件切分成小块,上传以后再拼接起来;
  2. 借助于 OSS,将文件先上传 OSS,函数从 OSS 上下载文件,处理完以后回传 OSS;
  3. 借助于 NAS,将大文件放在 NAS 网盘上,函数可以像读写普通文件系统一样访问 NAS 网盘的文件。

快速开始

安装依赖

在开始之前请确保开发环境已经安装了如下工具:

  • docker
  • funcraft
  • git
  • make

构建并启动函数

克隆代码:

git clone https://github.com/vangie/fc-file-transfer

本地启动函数:



$ make start
...
HttpTrigger httpTrigger of file-transfer/nodejs was registered
        url: http://localhost:8000/2016-08-15/proxy/file-transfer/nodejs
        methods: [ 'GET', 'POST' ]
        authType: ANONYMOUS
HttpTrigger httpTrigger of file-transfer/python was registered
        url: http://localhost:8000/2016-08-15/proxy/file-transfer/python
        methods: [ 'GET', 'POST' ]
        authType: ANONYMOUS
HttpTrigger httpTrigger of file-transfer/java was registered
        url: http://localhost:8000/2016-08-15/proxy/file-transfer/java
        methods: [ 'GET', 'POST' ]
        authType: ANONYMOUS
HttpTrigger httpTrigger of file-transfer/php was registered
        url: http://localhost:8000/2016-08-15/proxy/file-transfer/php
        methods: [ 'GET', 'POST' ]
        authType: ANONYMOUS
function compute app listening on port 8000!

make start 命令会调用 Makefile 文件中的指令,通过 fun local 在本地的 8000 端口开放 HTTP 服务,控制台会打印出每个 HTTP Trigger 的 URL 、支持的 HTTP 方法,以及认证方式。

效果演示

上面四个 URL 地址随便选一个在浏览器中打开示例页面。

接口说明

所有示例都实现了下述四个 HTTP 接口:

  • GET / 返回文件上传 Form 的 HTML 页面
  • GET /list 以 JSON 数组形式返回文件列表
  • POST /upload以multipart/form-data格式上传文件fileContent 作为文件字段fileName 作为文件名字段
  • GET /download?filename=xxx 以 application/octet-stream 格式返回文件内容。

此外为了能正确的计算相对路径,在访问根路径时如果不是以/结尾,都会触发一个 301 跳转,在 URL 末尾加上一个/。

不同语言的示例代码

  • nodejs
  • python
  • php
  • java

已知问题

  1. 文件大小限制
  2. fun local 实现存在已知问题,上传过大的文件会自动退出,未来的版本会修复。
  3. 部署到线上需要绑定自定义域名才能使用,否则 HTML 文件在浏览器中会被强制下载而不是直接渲染。

查看更多:https://yq.aliyun.com/articles/743642?utm_content=g_1000103098

上云就看云栖号:更多云资讯,上云案例,最佳实践,产品入门,访问:https://yqh.aliyun.com/