一.場(chǎng)景
? ? ? ? 昨天公司里面提了一個(gè)需求,將競(jìng)爭(zhēng)對(duì)手的sku通過(guò)一些手段導(dǎo)入我們自己的數(shù)據(jù)庫(kù),普通數(shù)據(jù)比較好搞,但是圖片這種靜態(tài)資源我們只能獲取到一個(gè)url,所以需要進(jìn)行一次轉(zhuǎn)存。
二.實(shí)現(xiàn)
? ? ? ? 這里有兩個(gè)思路,一個(gè)是交給后端來(lái)做這個(gè)事情,但是后端做的話,會(huì)暴露我們自己的后端,給對(duì)手留下痕跡。第二個(gè)就是前端來(lái)做,每次使用不同的電腦訪問(wèn)網(wǎng)站來(lái)做這個(gè)數(shù)據(jù)轉(zhuǎn)存的操作就給追蹤提高難度,因?yàn)閷?duì)方也不知道我們是否是正常的訪問(wèn)資源。
? ? ? ? 最終選擇了前端來(lái)做。第一步,通過(guò)http獲取到該網(wǎng)站的數(shù)據(jù),模擬登錄獲取token,截取下來(lái)他的商品列表數(shù)據(jù)。這個(gè)就不貼代碼了,也可以通過(guò)不使用代碼的方式來(lái)實(shí)現(xiàn)。
? ? ? ? 第二步。將獲取到的商品數(shù)據(jù)里面的圖片讀取出來(lái)并上傳
/**
* @descrip 將blob對(duì)象轉(zhuǎn)換成file對(duì)象
* @param {Blob} blob 需要轉(zhuǎn)換成文件的blob對(duì)象
* @param {string} fileName 文件名
* @param {string} fileType 文件類型
* @return {Promise} 返回一個(gè)promise對(duì)象,即處理之后的文件對(duì)象
**/
const transToFile = async(blob, fileName, fileType) => {
return new window.File([blob], fileName, { type: fileType })
}
/**
* @descrip 將互聯(lián)網(wǎng)上面的圖片讀取成buffer并且轉(zhuǎn)存至私有的服務(wù)器
* @param {string} url 需要轉(zhuǎn)換成的圖片的公網(wǎng)地址 eg:https://image.xxx.com/uploads/image/product/62b2babba1c9c_thumb.jpg
* @return {Promise} 返回一個(gè)promise對(duì)象,即上傳成功之后的圖片url
**/
const getFileStreamAndUpload = async (url) => {
return new Promise((resolve, reject) => {
let suffix = "jpg"
let fileNameArr = url.split("/")
let fileName = fileNameArr[fileNameArr.length - 1]
if (url.split(".").length > 1) {
suffix = url.split(".")[1]
}
// 通過(guò)axios讀取圖片時(shí)一定要加上這個(gè)responseType,不然是亂碼
axios.get(url, {responseType: 'arraybuffer'}).then(async res => {
// 構(gòu)建blob對(duì)象
const blob = new Blob([res.data], { type: `image/${suffix};charset=utf-8` })
let getFile = transToFile(blob, fileName, `image/${suffix}`)
getFile.then(async res1 => {
// 通過(guò)FormData將文件提交給后端
let formData = new FormData()
formData.append('file', res1)
formData.append('folderName', "fsImage")
let res2 = await bar.uploadFile(formData)
if (res2.code == 200) {
resolve(res2.data)
} else {
reject(new Error("圖片上傳失敗"))
}
})
})
})
}
// 獲取數(shù)據(jù)成功之后
const loadingInstance = ElLoading.service({ fullscreen: true })
// 這里的res.data.data 就是競(jìng)爭(zhēng)對(duì)手的商品列表數(shù)據(jù)
let fsData = res.data.data
for (let i = 0; i < fsData.length; i++) {
const item = fsData[i];
// 這里可能會(huì)出現(xiàn)跨域請(qǐng)求資源的情況所以使用代理將真實(shí)的域名代理到本地的開發(fā)服務(wù)器上面
item.productUrl = await getFileStreamAndUpload(item.thumb_path.replace("https://image.xxx.com", "/fsimgapi"))
}
console.log(fsData);
loadingInstance.close()
ElMessage.success("數(shù)據(jù)轉(zhuǎn)移成功")
?效果圖,這里轉(zhuǎn)換完成之后就直接輸出了一個(gè)轉(zhuǎn)換后的數(shù)組出來(lái),后續(xù)根據(jù)業(yè)務(wù)需求將這個(gè)數(shù)組提交給后端即可。
?
?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-623663.html
三.總結(jié)?
其實(shí)這種功能最好還是由后端或者nodejs來(lái)做,純前端不可避免的會(huì)遇到跨域問(wèn)題。主要的技術(shù)要點(diǎn)就是將網(wǎng)絡(luò)上面的靜態(tài)資源通過(guò)讀取成流的形式放在瀏覽器緩存里面,然后利用Blob對(duì)象跟File對(duì)象之間的互相轉(zhuǎn)換,就可以得到一個(gè)個(gè)的文件對(duì)象了,最后通過(guò)FormData將數(shù)據(jù)上傳即可。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-623663.html
到了這里,關(guān)于前端通過(guò)http獲取圖片流并轉(zhuǎn)存的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!