微信公众号生成带参数的二维码developers.weixin.qq.com/doc/offiacc…
在h5+vue中使用html2canvas生成海报时,直接访问mp.weixin.qq.com/cgi-bin/sho… 出现跨域问题
1.设置useCORS: true,crossorigin="anonymous"
这篇文章中分析得比较详细 www.jianshu.com/p/22bd5b98e…
其中,总结了跨域解决方式
通过查看微信公众号二维码接口响应头,没有Access-Control-Allow-Origin
2.调用后端接口,返回图片数据
既然前端访问会跨域,那我从后端获取图片数据,再返回给前端。
后端接口
@GetMapping("/image")
public ResponseEntity<byte[]> getImage() throws IOException {
String wxQRCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=XXX";
RestTemplate restTemplate = new RestTemplate();
byte[] imageBytes = restTemplate.getForObject(wxQRCodeUrl, byte[].class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG); // 设置图片类型,可根据实际情况修改
return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
}
前端获取图片
getImage() {
const apiUrl = 'http://localhost:80/XXX/image'; // 与后端接口的URL保持一致
axios.get(apiUrl, { responseType: 'arraybuffer' })
.then(response => {
const imageBlob = new Blob([response.data], { type: response.headers['content-type'] });
// 使用wxQRCodeUrl保存图片地址,记得再前面定义
this.wxQRCodeUrl = URL.createObjectURL(imageBlob);
})
.catch(error => {
console.error(error);
});
}
3.html2cavas
使用tn-popup实现弹窗效果,当showQrcode为true时弹窗,其它组件应该有自己的弹窗方法;第一张图片是海报背景图,第二张图片是二维码图,当然可以添加text文字等,通过class的css可以调整图片和文字的位置,createPoster方法会让以上的排版最终形成一张完整的海报图片,也就是第三个image。
<tn-popup v-model="showQrcode" mode="center">
<view class="canvas-wrap">
<view class="canvas-content-wrap mb20" id="poster" v-if="!imageData">
<image :src="originalPosterUrl" class="original-poster" mode="widthFix" crossorigin="anonymous"></image>
<image :src="qrImageUrl" class="qr-image" crossorigin="anonymous"></image>
</view>
<image :src="postImageData" mode="widthFix" v-else></image>
<button type="primary" @click="createPoster" class="mb20">生成海报</button>
</view>
</tn-popup>
createPoster方法
npm install html2canvas
createPoster() {
uni.showLoading({
title: '正在生成海报'
})
let dom = document.querySelector('#poster')
html2canvas(dom, {
width: dom.clientWidth, //dom 原始宽度
height: dom.clientHeight,
scrollY: 0,
scrollX: 0,
useCORS: true
}).then((canvas) => {
uni.hideLoading()
//成功后调用返回canvas.toDataURL返回图片的postImageData
this.postImageData = canvas.toDataURL('image/png', 1)
})
},
本文CSS
.canvas-wrap {
padding: 40rpx;
text-align: center;
.canvas-content-wrap {
background: rgb(224, 187, 63);
display: flex;
flex-direction: column;
align-items: center;
color: #ffffff;
padding: 20rpx;
z-index: -1;
.original-poster {
height: 200rpx;
margin-bottom: 40rpx;
z-index: 1;
}
.qr-image {
position: absolute;
top: 60%;
/* 调整第二张图片的垂直位置 */
left: 60%;
/* 调整第二张图片的水平位置 */
width: 100px;
/* 调整第二张图片的宽度 */
height: 100px;
z-index: 99;
}
.poster-title {
font-size: 32rpx;
margin-bottom: 40rpx;
}
}
}
最终展示
4.补充
(1)后端也可以返回图片的byte[]数据
this.imageUrl = 'data:image/jpeg;base64,' + response.data.data;
(2)生成海报后,图片清晰度下降
将海报图和二维码的image换成img,清晰度提高不少