JavaScript download link image after upload

Since to upload images, so the first time, of course, is to determine whether to download pictures of resources, sometimes you can use regular expressions, but it is difficult to determine whether can be downloaded, when whether after image links have the suffix is upset, some pictures are no suffix, but if let go of the restrictions and are more likely to be attacked, Therefore, we use Image as a judgment method here. If the Image is successfully loaded, it means that it is indeed an Image and can be downloaded.

// Determine if the link points to an image and is downloadable
export const checkImgExists = (imgurl: string) = > {
  return new Promise(function (resolve, reject) {
    var ImgObj = new Image();
    ImgObj.src = imgurl;
    ImgObj.onload = function (res) {
      resolve(res);
    };
    ImgObj.onerror = function (err) {
      reject(err);
    };
  });
};

// how to use it
checkImgExists(imgLink)
  .then(() = > {
    // do something with imgLink
    console.log(imgLink);
  })
  .catch((err) = > {
    // some log or alarm
    console.log(err);
    console.log("Sorry, this link can't get images.");
  });
Copy the code

After that, we need to download the image. In this case, we use XMLHttpRequest to request the download and it will be a Blob object.

Blobs themselves can be converted into FormData objects or File objects, which can be uploaded according to the specific situation of your project. If you want to upload to OSS, you can choose to convert to File objects, and if you want to transfer to your own server, you can use Ajax. And upload Blob as FormData.

// Make an XMLHttpRequest request to the image in the image link to return the Blob object
function getImageBlob(url: string) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open("get", url, true);
    xhr.responseType = "blob";
    xhr.onload = function () {
      if (this.status == 200) {
        resolve(this.response); }}; xhr.onerror = reject; xhr.send(); }); }// Convert Blob objects to File objects
const blobToFile = (blob: Blob, fileName: string) = > {
  return new window.File([blob], fileName, { type: blob.type });
};

// how to use it
// Returns a File object that can be used for uploading operations
getImageBlob(src).then(async (res: any) = > {const srcSplit = src.split("/");
  const filename = srcSplit[srcSplit.length - 1];
  return blobToFile(res, filename);
});
Copy the code

Next is a small demonstration of uploading OSS. Since OSS involves a lot of privacy information, it is recommended that you use interfaces to obtain accessKeyId, accessKeySecret and other information, and even use temporary keys.

import OSS from "ali-oss";

const ERROR_TIP = "Upload failed!";

/** * File Example of uploading OSS * accessKeyId, bucket and other parameters need to be filled according to your OSS library * it is recommended to use [accessKeyId, accessKeySecret] as an interface to obtain or encrypt the two sensitive information */
export const uploadToOSS = async (
  fileName: string.file: File,
  accessKeyId: string.accessKeySecret: string. props ) => {let client = new OSS({
    endpoint, // You applied for the oss project address
    bucket, // OSS object carrier
    accessKeyId, // your accessKeyId with OSS
    accessKeySecret, // your accessKeySecret with OSS
    internal: true. props, });const putResult = await client.put(fileName, file, {
    timeout: 60 * 1000 * 2});if (putResult.res.status === 200) {
    return { url: putResult.url, fileName };
  }
  throw new Error(ERROR_TIP);
};
Copy the code

Of course, if you want to upload images to your own server, you can choose to convert Blob files to FormData format and upload images using XMLHttpRequest or Ajax

// Convert Blob objects to FormData objects
const blobToFormData = (blob: Blob, fileName: string) = > {
  const formdata = new FormData();
  formdata.append("file", blob, fileName);
  return formdata;
};

// XMLHttpRequest
const uploadFile = (formData: FormData) = > {
  const url = "your_interface";
  let xhr = new XMLHttpRequest();
  xhr.onload = function () {
    console.log("ok");
    console.log(JSON.parse(xhr.responseText));
  };
  xhr.onerror = function () {
    console.log("fail");
  };
  xhr.open("post", url, true);
  xhr.send(formData);
};

// Ajax
const uploadFile2 = (formData: FormData) = > {
  const url = "your_interface";
  $.ajax({
    url,
    type: "POST".data: formData,
    async: false.cache: false.contentType: false.processData: false.success: function (returndata) {
      console.log(returndata);
    },
    error: function (returndata) {
      console.log(returndata); }}); };Copy the code

In my previous back-end project, I used Express as a static image library. Here is my Node upload image code. Note that while formidable resolves, JPG files will have a long, random name in your default photo directory. Actually, I’ve renamed them with a shorter name, so you can choose your own renaming strategy.

const express = require("express");
const listenNumber = 5000;
const app = express();
const bodyParser = require("body-parser");
const http = require("http"); // Create the server
const formidable = require("formidable");
const path = require("path");
const fs = require("fs");
app.use(express.static(".. /.. /upload"));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // The data type is JSON

// Upload the image
app.post("/upLoadArticlePicture".(req, res, next) = > {
  let defaultPath = ".. /.. /upload/";
  let uploadDir = path.join(__dirname, defaultPath);
  let form = new formidable.IncomingForm();
  let getRandomID = () = >
    Number(Math.random().toString().substr(4.10) + Date.now()).toString(36);
  form.uploadDir = uploadDir; // Set the cache directory for uploading files
  form.encoding = "utf-8"; // Set edit
  form.keepExtensions = true; // Keep the suffix
  form.maxFieldsSize = 2 * 1024 * 1024; // File size
  form.parse(req, function (err, fields, files) {
    if (err) {
      res.locals.error = err;
      res.render("index", { title: TITLE });
      return;
    }
    let filePath = files.file["path"];
    let backName = filePath.split(".") [1];
    let oldPath = filePath.split("\ \")[filePath.split("\ \").length - 1];
    let newPath = `${getRandomID()}.${backName}`;
    fs.rename(defaultPath + oldPath, defaultPath + newPath, (err) = > {
      if(! err) { newPath =`http://localhost:${listenNumber}/${newPath}`;
        res.json({ flag: true.path: newPath });
      } else {
        res.json({ flag: false.path: ""}); }}); }); });Copy the code