In this paper, a personal blog address: https://www.leafage.top/posts/detail/21414BX0U

Leafage-MS project has been written for a long time, but the function of uploading files has not been completed. I read the documents of Qniuyun for several times before, but failed. Today, I made up my mind to solve this problem, so I started to look for various materials, read documents and read examples, and finally got it done.

The project is built by vite.js, and it uses TypeScript. There are almost no examples on the Internet. Here is how to achieve it step by step.

First install Qiniu-js and Crypto-js. Qiniu-js is the upload, Crypto-js is the crypto tool used to generate tokens. The installation command is as follows:

yarn add crypto-js qiniu-js -D

Create a new upload.ts file in the tool/plugin directory, and refer to the official document to write the upload method. The method of encrypting and generating tokens is the first upload method, and the final code is as follows:

import * as qiniu from 'qiniu-js'; Import CryptoJS from 'crypto-js' export function uploadFile(file: File) { const uptoken = getToken("ss", "xx", "xx"); const key = file.name; Const config = {usecdnDomain: true, region: qiniu.region. Z2, ForceDirect: true}; Const putExtra: any = {fname: file.name, // ['image/ PNG ', 'image/jpeg', 'image/ GIF '] // NULL means no file type restriction; }; return qiniu.upload(file, key, uptoken, putExtra, config); }

Note that what is returned is the execution result of the upload(), which is an object containing next, error and complete. The process and result are not processed here, but directly returned and processed in the place used.

The uploadFile() method needs to be exposed for use in the component

The three parameters of getToken() method are: accessKey, secretKey, and bucketName. You need to log in your Qinuyun account to see the specific operation. After logging in, click the head picture, and then click key management, you can see the final code of getToken() method is as follows:

Function getToken(access_key: string, secret_key: string, bucketname: string) {// Construct policy var putPolicy = {"scope": bucketname, "deadline": 3600 + Math.floor(Date.now() / 1000) } var encoded = base64Encode(utf16to8(JSON.stringify(putPolicy))); var hash = CryptoJS.HmacSHA1(encoded, secret_key); / / structure credentials var encodedSign = hash. ToString (CryptoJS. Enc. Base64). Replace (/ / / / g, '_'). The replace (/ \ + / g, '-'); var uploadToken = access_key + ':' + encodedSign + ':' + encoded; return uploadToken; }

The base64Encode() and utf16to8() methods in getToken() are implemented as follows:

function base64Encode(str: string) {
    var out, i, len;
    var c1, c2, c3;
    len = str.length;
    i = 0;
    out = "";
    var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
    while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}
function utf16to8(str: string) {
    var out, i, len, c;
    out = "";
    len = str.length;
    for (i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if ((c >= 0x0001) && (c <= 0x007F)) {
            out += str.charAt(i);
        } else if (c > 0x07FF) {
            out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
            out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        } else {
            out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        }
    }
    return out;
}

The entire upload method is completed and then used in the component, as shown below:

import { uploadFile } from ".. /.. /plugins/upload";

To add a control to the HTML, here’s an example:

<div class="mx-auto text-center"> <div class="text-center text-gray-600"> <label for="file-upload" class="relative cursor-pointer bg-white rounded-md text-gray-400 hover:text-indigo-500" > <svg class="mx-auto h-8 w-8" stroke="currentColor" fill="none" viewBox="0 0 48 48" aria-hidden="true" > <path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0V8A4 4 0 01-4 4H12A4 0 01-4-4V-4M32-4L-3.172-3.172A4 4 0 00-5.656 0L28 28M8 32L9. 172-9.172A4 4 0 015.656 0L28 28M0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> </svg> <input id="file-upload" name="cover" type="file" class="sr-only" accept="image/png,image/jpeg,image/jpg" @change="uploadImage($event.target.files)" /> </label> </div> <p class="text-xs text-gray-500">png, jpeg, jpg</p> <p class="text-xs text-gray-500">up to 2MB</p> </div>

To call the uploadFile method in the method, the following example uploads only one file:

UploadImage (files: Array<File>) {if (files.length > 0) {UploadFile (files[0]).subscribe({next: (result) => { }, error: () => { }, complete: (e) => { let data = { ... this.postsData, cover: "https://cdn.leafage.top/" + e.key, }; this.postsData = data; }}); }},

It’s not easy to get here and make it.