最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript 下载链接图片后上传

    正文概述 掘金(开心的米卡)   2021-03-07   475

    JavaScript 下载链接图片后上传

       既然要进行图片上传,那么第一时间当然是判断是否为可下载的图片资源,有的时候可以使用正则表达式,但是很难判断是否可下载,当判断图片链接后是否有后缀的时候也比较苦恼,有的图片是没有后缀的,可是如果放开这个限制又比较容易被攻击,所以这里我们使用 Image 作为判断手法,若成功加载图片,那么说明确实为图片且可下载。

    // 判断链接是否指向图片且可下载
    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("很抱歉, 该链接无法获取图片");
      });
    

       判断好后,我们需要对这个图片进行下载,这里我们使用 XMLHttpRequest 进行请求下载,下载后会是一个 Blob 对象。

       Blob 本身可以转化成 FormData 对象或者是 File 对象,我们可以根据自己项目的具体情况去选择上传策略,如果想传到 OSS 上,可以选择转化为 File 对象,若是传输到自己的服务器上,可以使用 Ajax,并转 Blob 为 FormData 进行上传。

    // 将图片链接中的图片进行 XMLHttpRequest 请求,返回Blob对象
    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();
      });
    }
    
    // 将Blob对象转为File对象
    const blobToFile = (blob: Blob, fileName: string) => {
      return new window.File([blob], fileName, { type: blob.type });
    };
    
    // how to use it
    // 返回一个File对象,可使用该 File 对象进行上传操作
    getImageBlob(src).then(async (res: any) => {
      const srcSplit = src.split("/");
      const filename = srcSplit[srcSplit.length - 1];
      return blobToFile(res, filename);
    });
    

       接下来是一个上传OSS的小演示,由于 OSS 涉及的隐私信息较多,所以建议大家把accessKeyId、accessKeySecret等信息用接口去获取,甚至使用临时的钥匙等。

    import OSS from "ali-oss";
    
    const ERROR_TIP = "上传失败!";
    
    /**
     * File上传OSS的示例
     * 相关accessKeyId、bucket等参数需要根据你的OSS库进行填写
     * 建议将【accessKeyId,accessKeySecret】这两个敏感信息做成接口获取或者加密
     */
    export const uploadToOSS = async (
      fileName: string,
      file: File,
      accessKeyId: string,
      accessKeySecret: string,
      ...props
    ) => {
      let client = new OSS({
        endpoint, // 你申请好的oss项目地址
        bucket, // OSS 对象载体
        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);
    };
    

       当然如果想上传图片到你自己的服务器,可以选择将 Blob 格式的文件转为 FormData 格式,使用 XMLHttpRequest 或者 Ajax 进行图片的上传

    // 将Blob对象转为FormData对象
    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);
        },
      });
    };
    

       在之前我的后端项目中,使用了 Express 作为静态图片库,以下是我的 node 上传图片代码。值得注意的是,使用 formidable 解析后,jpg 文件会直接在你的预设照片目录有一个很长的随机名称,这边其实我也是使用了较短的名称进行重命名,大家可以根据自己的需要选择重命名策略。

    const express = require("express");
    const listenNumber = 5000;
    const app = express();
    const bodyParser = require("body-parser");
    const http = require("http"); //创建服务器的
    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()); //数据JSON类型
    
    // 上传图片
    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; //设置上传文件的缓存目录
      form.encoding = "utf-8"; //设置编辑
      form.keepExtensions = true; //保留后缀
      form.maxFieldsSize = 2 * 1024 * 1024; //文件大小
      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: "" });
          }
        });
      });
    });
    

    起源地下载网 » JavaScript 下载链接图片后上传

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元