Yesterday I encountered a problem with a backend transport causing nginx502

After tweaking the code today, I posted the solution

Advantages of front-end direct transfer: it reduces the pressure on the application server and transfers the pressure to OSS, which is especially obvious when uploading large files. PHP consumes a large part of the memory to process the files from the front-end shard and then transfer them to OSS. If the files are too large and time-consuming, NGINX will directly transfer them to the OSS
502We don’t need to narrow the path by tweaking the Nginx timeout. Direct from the client to OSS.

Renderings after completion

becausedcat-adminIt’s highly encapsulated. It’s almost impossible to change the components, but$form->view()Method to import a view file. My idea is to encapsulate an uploaded component with VUE and then introduce it in this way. It just so happens that Laravel provides the front end scaffoldinglaravel mixIntegration of Vue.

  • Laravel version 7. X

#### Start a set of shuttles

NPM install NPM install ali-oss --save // Install the new composer require laravel/ UI --dev // Install the new composer require laravel/ UI --dev / Js-sdk NPM install clipboard --save NPM run watch //

A component that uses Element-UI, so we introduced it

npm i element-ui -S

inapp.jsFile global loading

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
import Clipboard from 'clipboard';
Vue.prototype.Clipboard=Clipboard;

And I’m gonna create a new componentOssFile

<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"> </el-button> <el-button style="margin-left: 10px;" Size ="small" type=" Upload" @Click =" Upload"> </el-button <el-button style="margin-left: 10px;" </ span > </ p > < p style="margin-left: 10px; margin-left: 10px; 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'; Const client = new OSS({region: 'oss-cn-shenzhen', accessKeyID: '', accessKeyID: ', accessKeyID: ', accessKeyID: ', ' ",// AccessKeySecret bucket: ",//bucket name}); export default { name: "OssFile", data () { return { fileName:"", fileList:[], file: null, tempCheckpoint: // Percentage of uploading status of progress bar: 0 // Percentage of uploading status of progress bar: 0 // Percentage of uploading status of progress bar: }}, mounted() {window.addEventListener('online', this.resumeUpload); }, methods: { copy() { var clipboard = new Clipboard(".copybtn"); On ("success", (e) = bb0 {this.$message({message: 'success', type: 'success'}); // Free the memory clipboard.destroy(); }); Clipboard. on("error", (e) => {// copy this.$message({message: 'This browser does not support automatic copy ', type: 'success'}); // Free the memory clipboard.destroy(); }); }, // Click to upload to server submitForm(file) {this.multipartupload (); } / / cancel upload shard event async abortMultipartUpload () {window. The removeEventListener (' online ', this.resumeUpload) const name = this.uploadName; // The full path to the Bucket where the Object resides. const uploadId = this.upload; // upload uploads to the database. const result = await client.abortMultipartUpload(name, uploadId); Console. log(result, '======= clear slice at '); }, // Pause the shard upload. StopUplosd () {window. RemoveEventListener (' online ', enclosing resumeUpload)/clearance/pause time listening let result = client. The cancel (); The console. The log (result, '-- -- -- -- -- -- -- -- -- pause -- -- -- -- -- -- -- -- -- -- -')}, / / section to upload async multipartUpload () {if (! This.file) {this.$message.error(' Please select file ') return} console.log("this.uploadStatus",this.file, this.uploadStatus); Console. log(" FileList :"+this.fileList) console.log(" File :"+this.file) this.percentage = 0 try { // Object-name can be customized as a filename (for example, file.txt) or directory (for example, ABC /test/file.txt) to upload the file to the current Bucket or to the specified directory under the Bucket. let result = await client.multipartUpload(this.file.name, this.file, { headers: { 'Content-Disposition': 'inline', 'content-type ': this.file.type // Note: This file is set according to the suffix of the image or file, and I used the'.png 'image to test}, 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 -- -- -- -- -- -- -- -- -- -- -') / / breakpoint record point. You cannot continue uploading directly after the browser is restarted. You need to manually trigger the upload operation. }, meta: { year: 2020, people: 'dev' }, mime: this.file.type }); Console. log(result, this.percentage, 'result= slice upload ='); 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 === 'ConnectionTimeOuError ') {this.uploadStatus =' Exception 'console.log(" TimeOuError "); }}}, // resume uploading. async resumeUpload () { window.removeEventListener('online', this.resumeUpload) if (! This. tempCheckPoint {this.$message.error(' Please upload first ') return} this.uploadStatus = null try {let result = await client.multipartUpload(this.file.name, this.file, { headers: { 'Content-Disposition': 'inline', 'Content-Type': This.file.type // Note: This file is set according to the suffix of the image or file, I used the '.png 'image, the details of which are described below}, progress: (p, checkpoint) => { this.percentage = p * 100 console.log(p, checkpoint, 'checkpoint---- restore the uploaded slice information. ') this.tempCheckpoint = checkpoint; }, checkpoint: this.tempCheckpoint, meta: { year: 2020, people: 'dev' }, mime: Enclosing the file. Type}) console. The log (result, 'the result - = - = - uploaded resume')} the catch (e) {the console. The log (e, 'e - = - = -'); }}, // select file changed handleChange(file, FileList) {this.filelist = fileList. Filter (row => row.uid == file.uid) this.file = file.raw This. submitForm(file)}, handleMove (file, fileList) {this.percentage = 0 this.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.jsIntroducing components in

Vue.component('oss-file', require('./components/uploads/OssFile.vue').default);

viewNew directoryoss.blade.phpThe introduction of the component <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>

The last

$form->html(view('uploads.oss')); $form->text('link',' link');

Perfect solution ~ ~ ~

Problems encountered

  • OSS cross-domain issues
  • Added ‘ETag x-oss-request-id’ to OSS error handling method

Refer to the article

  • OSS document * RequestId error handling method in Ali OSS