昨天遇到了一个后端传输导致nginx502的问题
明天在调整了代码之后,遂将解决方案贴出
前端直传的益处:加重应用服务器的压力,将压力分给了oss 这一点特地是在上传大文件时特地显著的,php是要耗费很大一部分内存去解决前端分片上传来的文件再传输给oss,如果文件特地大,耗时长nginx会间接502
咱们没必要去调整nginx的超时工夫把路走窄了。间接由客户端直传oss吧。
实现后效果图
因为dcat-admin
是高度封装的。改它的组件根本不事实,不过$form->view()
办法能够引入一个视图文件.我的想法是用vue封装一个上传的组件,而后通过该办法引入。正好laravel提供了前端脚手架laravel mix 整合了vue。
- laravel版本7.x
#### 开始一套梭
composer require laravel/ui --dev //装置前端脚手架php artisan ui vue //公布vue文件npm installnpm install ali-oss --save //装置oss js-sdknpm install clipboard --save //装置复制插件npm run watch //命令监督热加载、编译
应用element-ui的组件,所以咱们引入它
npm i element-ui -S
在app.js
文件全局加载
import ElementUI from 'element-ui';import 'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI);import Clipboard from 'clipboard';Vue.prototype.Clipboard=Clipboard;
并新建组件OssFile
<template> <div> <el-upload class="upload-demo" action="" ref="upload" :file-list="fileList" :limit="2" :on-change="handleChange" :on-remove="handleRemove" :auto-upload="false" accept="" > <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="submitForm">直传oss</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="resumeUpload">持续</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="stopUplosd">暂停</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="abortMultipartUpload">革除切片</el-button> </el-upload> <el-progress :percentage="percentage" :status="uploadStatus"></el-progress> <span class="copybtn" @click="copy" :data-clipboard-text="fileName" >{{ fileName }}</span> </div></template><script>import Clipboard from 'clipboard';let OSS = require('ali-oss') // 引入ali-oss插件const client = new OSS({ region: 'oss-cn-shenzhen',//依据那你的Bucket地点来填写 accessKeyId: '',//本人账户的accessKeyId accessKeySecret: '',//本人账户的accessKeySecret bucket: '',//bucket名字});export default { name: "OssFile", data () { return { fileName:"", fileList:[], file: null, tempCheckpoint: null, // 用来缓存以后切片内容 uploadId: '', uploadStatus: null, // 进度条上传状态 percentage: 0, // 进度条百分比 uploadName: '', //Object所在Bucket的残缺门路 } }, mounted() { window.addEventListener('online', this.resumeUpload); }, methods: { copy() { var clipboard = new Clipboard(".copybtn"); clipboard.on("success", (e) => { this.$message({ message: '复制胜利', type: 'success' }); // 开释内存 clipboard.destroy(); }); clipboard.on("error", (e) => { // 不反对复制 this.$message({ message: '该浏览器不反对主动复制', type: 'success' }); // 开释内存 clipboard.destroy(); }); }, // 点击上传至服务器 submitForm(file) { this.multipartUpload(); }, // 勾销分片上传事件 async abortMultipartUpload() { window.removeEventListener('online', this.resumeUpload) const name = this.uploadName; // Object所在Bucket的残缺门路。 const uploadId = this.upload; // 分片上传uploadId。 const result = await client.abortMultipartUpload(name, uploadId); console.log(result, '=======革除切片===='); }, // 暂停分片上传。 stopUplosd () { window.removeEventListener('online', this.resumeUpload) // 暂停时革除工夫监听 let result = client.cancel(); console.log( result, '---------暂停上传-----------') }, // 切片上传 async multipartUpload () { if (!this.file) { this.$message.error('请抉择文件') return } console.log("this.uploadStatus",this.file, this.uploadStatus); console.log("文件列表:"+this.fileList) console.log("文件:"+this.file) this.percentage = 0 try { //object-name能够自定义为文件名(例如file.txt)或目录(例如abc/test/file.txt)的模式,实现将文件上传至以后Bucket或Bucket下的指定目录。 let result = await client.multipartUpload(this.file.name, this.file, { headers: { 'Content-Disposition': 'inline', 'Content-Type': this.file.type //留神:依据图片或者文件的后缀来设置,我试验用的‘.png’的图片,具体为什么下文解释 }, progress: (p, checkpoint) => { this.tempCheckpoint = checkpoint; this.upload = checkpoint.uploadId this.uploadName = checkpoint.name this.percentage = p * 100 // console.log(p, checkpoint, this.percentage, '---------uploadId-----------') // 断点记录点。浏览器重启后无奈间接持续上传,您须要手动触发上传操作。 }, meta: { year: 2020, people: 'dev' }, mime: this.file.type }); console.log(result, this.percentage, 'result= 切片上传完毕='); this.$nextTick(()=>{ this.fileName = 'https://image.mythinkcar.cn/'+result.name }) console.log(this.fileName) } catch (e) { console.log(e) window.addEventListener('online', this.resumeUpload) // 该监听放在断网的异样解决 // 捕捉超时异样。 if (e.code === 'ConnectionTimeoutError') { // 申请超时异样解决 this.uploadStatus = 'exception' console.log("TimeoutError"); } } }, // 复原上传。 async resumeUpload () { window.removeEventListener('online', this.resumeUpload) if (!this.tempCheckpoint) { this.$message.error('请先上传') return } this.uploadStatus = null try { let result = await client.multipartUpload(this.file.name, this.file, { headers: { 'Content-Disposition': 'inline', 'Content-Type': this.file.type //留神:依据图片或者文件的后缀来设置,我试验用的‘.png’的图片,具体为什么下文解释 }, progress: (p, checkpoint) => { this.percentage = p * 100 console.log(p, checkpoint, 'checkpoint----复原上传的切片信息-------') this.tempCheckpoint = checkpoint; }, checkpoint: this.tempCheckpoint, meta: { year: 2020, people: 'dev' }, mime: this.file.type }) console.log(result, 'result-=-=-复原上传完毕') } catch (e) { console.log(e, 'e-=-=-'); } }, // 抉择文件产生扭转 handleChange(file, fileList) { this.fileList = fileList.filter(row => row.uid == file.uid) this.file = file.raw // 文件扭转时上传 // this.submitForm(file) }, handleRemove(file, fileList) { this.percentage = 0 //进度条置空 this.fileList = [] }, }}</script><style>.avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden;}.avatar-uploader .el-upload:hover { border-color: #409EFF;}.avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 150px; height: 150px; line-height: 150px; text-align: center;}.avatar { width: 150px; height: 150px; display: block;}</style>
app.js
中引入组件
Vue.component('oss-file', require('./components/uploads/OssFile.vue').default);
view
目录新建oss.blade.php
引入组件 <oss-file></oss-file>
<link rel="stylesheet" href="{{mix('css/app.css')}}"><div id="app"><div class="container"> <oss-file></oss-file></div></div><script src="{{mix('js/app.js')}}"></script>
最初
$form->html(view('uploads.oss')); $form->text('link','直传后填入地址');
完满解决~~~
碰到的问题
- oss 跨域问题
- oss 呈现 RequestId 错误处理办法 新增`ETag
x-oss-request-id`
参考文章
- oss文档
*阿里 oss 呈现 RequestId 错误处理办法