The server uploads the file
The server will transfer the image source to seven Cows, this way the process is
1 the front end will transmit the picture to its own server. 2 The server will transfer the file to seven cows
- API
The front end
Note that you want to use formData format for file uploads, about formData
document.querySelector('input').onchange = (a)= > {
const file = document.querySelector('input').files[0]
let formData = new FormData()
formData.append('file', file)
// fetch calls the interface
fetch(path, {
body: formData,
credentials: 'same-origin'.method: 'POST'})}Copy the code
Server Interface
- The basic parameters
const bucket = 'cancan'
const accessKey = '2LC7KPjwnYdxxxc'
const secretKey = 'SXrxxx'
const domain = 'http://pq3xxxdn.com'
Copy the code
- Access token
function get_token () {
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const policyParams = { scope: bucket }
const putPolicy = new qiniu.rs.PutPolicy(policyParams);
const uploadToken = putPolicy.uploadToken(mac);
return uploadToken
}
Copy the code
- Upload the file path after you get it
async function uploadFile(localFile, key) {
const uploadToken = get_token()
const config = new qiniu.conf.Config();
// Space corresponding to the machine room
config.zone = qiniu.zone.Zone_z0;
const formUploader = new qiniu.form_up.FormUploader(config);
const putExtra = new qiniu.form_up.PutExtra();
return new Promise((resolve, reject) = > {
// File upload
formUploader.putFile(uploadToken, key, localFile, putExtra, function (respErr, respBody, respInfo) {
if (respErr) {
reject('error')}if (respInfo.statusCode == 200) {
const { key } = respBody
resolve(`${domain}/${key}`)}}); })}Copy the code
- interface
router.post('/upload'.async (ctx) => {
// Get the file information uploaded to the server
const { img } = ctx.request.files
// path gets the temporary file address
const { path } = img
// key is the name of the image
const key = Math.random() * 100 + '.png'
const result = await uploadFile(path, key)
ctx.body = result
})
Copy the code
Problems encountered
- The POST interface was never able to resolve to the file parameter
It turns out that the middleware only uses koA-BodyParser, and the general image uploads use Koa-multer. You can use Koa-Body instead of both
Refer to the article
- Temporary files take up a lot of disk space
As you can see, when the file is uploaded to the server, a temporary file is created – the path that is resolved in the interface
For the server, you can write a timed script to clean up these files. Or we could add a piece of logic to the script to manually delete the temporary file after a successful upload to Qiniu
fs.unlink(path, (err) => {
if (err) throw err;
console.log('File deleted', path);
})
Copy the code
- Git address – server
- Git address – HTML
Front-end direct upload
The example in the project involves the image uploading, which is to upload the file to the server and then to the seven cow space. This mode of operation is equivalent to making a layer of transfer station in their own server. The developer can do some processing on the image in the transfer station and then upload it to the seven ox space. But there are some disadvantages
-
The memory usage increases
-
Temporary files occupy disk space and need to be deleted after each upload
If you don’t need a transfer station in your development, consider uploading images directly from the front end to Seven Cow Space
Refer to the API documentation of seven Cows, basically can be involved in
-
Generation of upload credentials
-
Front-end file upload
-
area
-
Set upload policy parameters
Obtain the upload certificate token
router.get('/qiniu'.async (ctx, next) => {
const bucket = 'activity'
const accessKey = '2LCxxxrxxx'
const secretKey = 'SXrdqdvxxx'
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const policyParams = { scope: bucket }
const putPolicy = new qiniu.rs.PutPolicy(policyParams);
const uploadToken = putPolicy.uploadToken(mac);
ctx.body = uploadToken
})
Copy the code
Front-end upload code
- Turn base64 blob
function base64ToBlob(dataurl) {
var arr = dataurl.split(', '),
mime = arr[0].match(/ : (. *?) ; /) [1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
Copy the code
- The basic parameters
// This token is returned by the server interface
const token = '2LC7KTxxx'
const config = {
useCdnDomain: true.region: qiniu.region.z1
};
const putExtra = {
fname: "".params: {},
mimeType: [] | |null
};
Copy the code
- Core to upload
const inputTarget = document.querySelector('input')
inputTarget.onchange = (data) = > {
const imgfile = inputTarget.files[0]
const reader = new FileReader();
reader.readAsDataURL(imgfile);
reader.onload = function (e) {
const urlData = this.result;
const blobData = base64ToBlob(urlData)
// The first argument here is of the form blob
const observable = qiniu.upload(blobData, 'filename.png', token, putExtra, config)
const observer = {
next(res) {console.log(res)},
error(err) {console.log(err)},
complete(res) {console.log(res)}
}
// Register an observer
observable.subscribe(observer)
}
}
Copy the code
The file can be sent to the Seven Cows
As you can see, this returns a hash and key. The complete access path at the end of the image is the domain +key configured on your server
If you create a new space in Seven Cows, you will be provided with a free domain name for 30 days
-
Git address – server
-
Git address – HTML
Problems encountered
- CdnUphost resolution failed
Turned out to be the
const config = {
useCdnDomain: true.region: 'qiniu.region.z0'
}
Copy the code
Region is wrong. It should not be a string, but a variable of seven cows
const config = {
useCdnDomain: true.region: qiniu.region.z0
}
Copy the code
This parameter depends on where your space storage area is selected, right
Select Z0, z1 against the document area
- The image cannot be read after uploading. The display is corrupted
This is because the first time you upload the input files[0] value, it is not in the format required by the documentation. The documentation requires that this parameter be bloB, so remember to convert the file format here
The previous demo has been written on the failure of shelving, today I ran again, once again ridicule the seven cattle document, write really let head big
Write webpack upload seven cattle plug-in
In development, there is a configuration to use a Webpack, qiniu-webpack-plugin
See how this works and write another upload plugin
Some of the documents involved
-
webpack plugin API
-
webpack plugin config
The plugin to use
// This is the folder to which the compiled files are compiled
const filePath = path.resolve(__dirname, 'public')
new QiuniuUploadPlugin({
bucket,
accessKey,
secretKey,
domain,
path: filePath
})
Copy the code
The realization of the class
Much of the logic of this is the same as uploading directly from the back end to seven Cows, so I’ll just write the other part here
- Outlined implementation
class QiuniuUploadPlugin {
constructor() {... } uploadQn (filename) {... } apply (compiler) {const pluginName = 'QiuniuUploadPlugin'
// Event hook
compiler.hooks.run.tap(pluginName, compilation => {
console.log("Webpack build process begins!")});// afterEmit - The asynchronous hook tapPromise is fired after the resource is generated to the output directory
compiler.hooks.afterEmit.tapPromise(pluginName, (compilation) => {
let { assets } = compilation
// Assets is an object. Key is the file name. Value is the related parameter
// assets -->>> { 'index.js' : xxxx }
// Upload the file through all the file names
const allUplaod = Object.keys(assets).map((item) = > {
return this.uplaodQn(item)
})
return Promise.all(allUplaod)
})
}
}
Copy the code
-
git – webpack
-
Implementation of git-plugin