1.シーン
昨日、同社は競合他社の SKU を何らかの方法で自社のデータベースにインポートするよう要求を出しました.一般的なデータは扱いやすいですが、画像などの静的リソースの URL は 1 つしか取得できないため、ダンプを実行する必要があります.
2.実現する
ここには2つのアイデアがあり、1つはこれをバックエンドに任せることですが、バックエンドがそれを行うと、私たち自身のバックエンドが公開され、相手に痕跡が残ります。2 つ目はフロント エンドで行うことです. 別のコンピューターを使用して Web サイトにアクセスし、このデータ転送操作を行うたびに、相手は私たちがリソースにアクセスしているかどうかわからないため、追跡がより困難になります.通常は。
結局、私はそれを行うためにフロントエンドを選びました。最初のステップは、http を介して Web サイトのデータを取得し、ログインをシミュレートしてトークンを取得し、製品リスト データを傍受することです。これはコードを投稿しません。また、コードを使用せずに達成することもできます。
第二段階。取得した商品データの写真を読み込んでアップロード
/**
* @descrip 将blob对象转换成file对象
* @param {Blob} blob 需要转换成文件的blob对象
* @param {string} fileName 文件名
* @param {string} fileType 文件类型
* @return {Promise} 返回一个promise对象,即处理之后的文件对象
**/
const transToFile = async(blob, fileName, fileType) => {
return new window.File([blob], fileName, { type: fileType })
}
/**
* @descrip 将互联网上面的图片读取成buffer并且转存至私有的服务器
* @param {string} url 需要转换成的图片的公网地址 eg:https://image.xxx.com/uploads/image/product/62b2babba1c9c_thumb.jpg
* @return {Promise} 返回一个promise对象,即上传成功之后的图片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]
}
// 通过axios读取图片时一定要加上这个responseType,不然是乱码
axios.get(url, {responseType: 'arraybuffer'}).then(async res => {
// 构建blob对象
const blob = new Blob([res.data], { type: `image/${suffix};charset=utf-8` })
let getFile = transToFile(blob, fileName, `image/${suffix}`)
getFile.then(async res1 => {
// 通过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("图片上传失败"))
}
})
})
})
}
// 获取数据成功之后
const loadingInstance = ElLoading.service({ fullscreen: true })
// 这里的res.data.data 就是竞争对手的商品列表数据
let fsData = res.data.data
for (let i = 0; i < fsData.length; i++) {
const item = fsData[i];
// 这里可能会出现跨域请求资源的情况所以使用代理将真实的域名代理到本地的开发服务器上面
item.productUrl = await getFileStreamAndUpload(item.thumb_path.replace("https://image.xxx.com", "/fsimgapi"))
}
console.log(fsData);
loadingInstance.close()
ElMessage.success("数据转移成功")
効果図では、変換が完了した後、変換された配列が直接出力され、ビジネス要件に従って配列をバックエンドに送信できます。
3. まとめ
実際、この種の機能はバックエンドまたは nodejs で行うのが最適であり、純粋なフロントエンドでは必然的にクロスドメインの問題が発生します。主な技術的ポイントは、ネットワーク上の静的リソースをストリームの形式でブラウザ キャッシュに読み込み、Blob オブジェクトと File オブジェクト間の相互変換を使用してファイル オブジェクトを 1 つずつ取得することです. 最後に、FormData を介してデータをアップロードします.