善战者不怒

发布于
批量获取公众号的图片并上传

善为士者,不武; 善战者,不怒; 善胜敌者,不与; 善用人者,为之下。 是谓不争之德,是谓用人之力,是谓配天古之极。

假设有一堆数据,提供了一些公众号文章的链接,使用的时候,需要手动添加封面图。 首页可能是一个 excel 表格文档,可以通过工具,将表格转为 JSON 数据。

先写一个函数,将公众号的图片的链接提取出来。

const mpLink2pic = async (link)=> { 
  const resp = await fetch(link)
  const b = await resp.blob()
  // 将网页 html 存为文本字符串
  const t= await b.text()
  const domparser = new DOMParser();
  // 然后解析为 html 文档
  const doc = domparser.parseFromString(t, "text/html");
  const picEl = doc.querySelector('p img')
  // 查询 html 文档中第一个 img 标签的 src 属性
  const pic = doc.querySelector('p img').dataset.src
  console.log('pic ',picEl, pic);
  return pic 
}

遍历数据列表,添加一个 pic 属性

list.forEach( async (x)=> { x.pic = await mpLink2pic(x.link) } )

然后下载并上传图片,这里需要添加请求头,不然微信公众号的图片会返回 参数错误 的 HTML:

const pic2Online = async (picLink)=> {
  // 获取图片
  const resp = await fetch(picLink, {
    "headers": {
      "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
      "accept-language": "zh-CN,zh-HK;q=0.9,zh;q=0.8,en-US;q=0.7,en;q=0.6",
      "cache-control": "max-age=0",
      "priority": "u=0, i",
      "sec-ch-ua": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\"",
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": "\"Windows\"",
      "sec-fetch-dest": "document",
      "sec-fetch-mode": "navigate",
      "sec-fetch-site": "cross-site",
      "sec-fetch-user": "?1",
      "sec-gpc": "1",
      "upgrade-insecure-requests": "1"
    },
    "referrer": "https://mp.weixin.qq.com/",
    "referrerPolicy": "strict-origin-when-cross-origin",
    "body": null,
    "method": "GET",
    "mode": "cors",
    "credentials": "omit"
  })
  const b = await resp.blob()
  // 尝试获取图片名称,一般是获取不到
  const filename = resp.headers.get("content-disposition")?.split("=")[1] ||
   ( 'pic-' + Date.now()  + '.' + b.type.split('/').at(-1) )
  // const t= await b.text()
  // const blobUrl = URL.createObjectURL(b);
  // console.log('b',{ t, resp, blobUrl,  b ,filename  });
  const file = new File(  [ b ], filename, { type:  b.type })
  // 转为文件对象然后上传
  console.log('file',file, filename );
  const formData = new FormData();
  formData.append('file', file );
  // 假设有一个上传的接口
  const respjson = await  fetch("/upload", {
    method: 'POST',
    body: formData,
    headers: {
        requestTime: Date.now() + '',
        timestamp: Date.now() + '',
        Authorization: 'bearerDispense',
    }
  })
  const rep = await respjson.json()
  // 服务器返回的地址
  const url = 'https://www.file/' + rep.data
  console.log('url',url );
  return url
}

调用这个函数,静候上传完成就行了

list.forEach( async (x)=> { x.pic = await pic2Online(x.pic) } )