> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# 图片上传「文件流」

## 业务需求：

- 文件上传在项目开发过程中是必不可少的一项功能。目前大多数文件上传都是采用文件流的形式进行上传。随着技术的进步，云服务技术的产生，现在上传文件相比原来更迅速、更方便，对上传文件的管理较之前来说方便了许多；
- 为兼顾原有的项目，上传文件没有采用现在使用比较多的阿里云 oss 文件直传，而是采用的后台辅助存储上传的形式来进行文件的存储。相对来说，文件上传比较慢，等待时间有点长。获取文件不像 oss 直传那样返回一个绝对的地址链接，而是返回的一个文件的 key，通过指定的参数拼接来换取图片地址；
- 此次简称为‘文件流上传’，前期开发的时候出现了一些错误，现将原有的文件流上传文件的具体实现步骤做相应分析处理，以便日后开发过程中使用。

## 效果图：

:::info 效果图

![效果图](data:image/png;base64,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)
- **注**：图片上传成功后，会在右侧灰色图片区域内进行展示。

:::

## 布局代码一：

:::info 代码案例
![布局代码](/static/image/10-2.5b8b01d282.png)
- **基于【 Vue 】**
- 采用 **elementUI** 的 **el-input** 标签与 **input** 文件上传标签相结合的方式；
- **wtLoading** 为 UI 框架的 **el-button** 按钮 **loading** 加载状态。

:::

## 样式代码：

```css title="CSS"
// 上传按钮样式布局
.uploadBtn {
	display: block;
	height: 100%;
	width: 100%;
	position: relative;
	overflow: hidden;
}

.uploadBtn > input[type="file"] {
	width: 100%;
	opacity: 0;
	cursor: pointer;
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
}
```

## 实现代码【 vue 】：

```javascript title="实现代码"
// 方式一：基于vue
uploadImg(file) {
	// 采用formData格式
	let fd = new FormData();
	fd.append("imgData", file);
	this.$axios
		.post("图片上传api", fd)
		.then(res => {
			let data = res.data;
			if (data.code == "1") {
				// 返回生成的图片ID
				this.imgGid = data.imgGid;
				// 拼接图片Id，获取绝对地址
				this.imageUrl = this.pic + data.imgGid;
				console.log('上传成功！')
			} else {
				console.log('上传失败！')
			}
		});
}
```

## 布局代码二：

:::info 布局代码
![布局代码](/static/image/10-3.31362f57a5.png)
- **基于【 JavaScript 】**
- 借助 **jQuery** 的 **form 表单** 提交实现二进制流文件上传；
- 上传的过程中会动态加载一张 loading.gif 动态图，当图片上传完成或者上传失败时候移除 loading 图。

:::

## 实现代码【 JavaScript 】：

```javascript title="实现代码"
const saveReport = function () {
    /* jQuery.form表单提交数据 */
    $("#addImg").ajaxSubmit({
        type: "post",
        url: "上传接口api",
        data: {
            picType: "jpg", // 图片格式
        },
        dataType: "json",
        success: function (res) {
            if (res.code == 1) {
                /* 生成的图片ID */
                avatars = res.imgGid;
                /* 拼接回显图片 */
                $("#upJPG").prepend(
                    '<img src="' + res.imgGid + '" class="imgStyle" />'
                );
                /* 删除图片 */
                $(".close").on("click", function (e) {
                    /* 阻止图片跳转 */
                    e.stopPropagation();
                    /* 对dom的操作 */
                });
            }
        },
        error: function (err) {
            hintCard("网络错误");
        },
    });
    /* 防止表单自己再次提交，并跳转页面 */
    return false;
};
```
