html2canvas跨域问题的坑

一、问题复现

环境是vue2 + python + django + nginx + uwsgi的线上服务环境。
最近在项目中发现一个关于html2canvas的问题,生成图片的时候莫名的出现跨域问题。就是页面有其他图片的时候,生成图片会报跨域问题,如下图:
注意:页面图片是直接从访问的django的静态文件夹下的图片的。如:http://xxxx/static/xxx.png
在这里插入图片描述
这包括已经给django添加了白名单,在django导入了中间件等操作,线下环境测试是正常的,线上生产环境就会出问题,使用了网上普遍的办法如下,都没有生效。

二、常见的解决方式一

在html2canvas添加useCORS的方式,并且在img标签中添加**crossorigin=“anonymous”**如下:

 html2canvas(document.querySelector("#capture"), {useCORS: true}).then(canvas => {
                ...
            });
<img :src="'http://xxxx/xxxx/xxx.png&time=' + new Date().getTime()" crossorigin="anonymous" alt=""/>

上面标签中拼接了一个new Date().getTime(),这是为了防止浏览器缓存,每次都是重新拿图片,后面接了一个**crossorigin=“anonymous”**这个属性会导致图片拿不到,但是我这里会继续报跨域问题。

三、常见的解决方式二:

基于上面添加useCORS的配置,通过Nginx模块Http_Headers_Module来添加Access-Control-Allow-Origin允许的地址。

add_header Access-Control-Allow-Origin *				# 这里的*是所有地址都可以去访问,线上环境建议写自己的地址
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

这些配置完成后,依然报跨域错误。

四、解决方案

在django中添加应用,单独写一个接口,通过django的HttpResponse方法去返回图片。
创建一个新的应用,这里就用命令去创建了,手动添加的记得注册一下这个应用。

# 项目根目录去执行
python manage.py startapp img
# urls文件中
from django.urls import path
from img.views import Img

urlpatterns = [
    path('img', Imag.as_view()),
]
# view文件中
import os
from django.conf import settings
from django.http import HttpResponse
from django.views import View


class Img(View):
	def get(self, request):
		try:
			# 这里获取的值为xxx.png
			img_path = request.GET.get('path', '')
			# 拼接完整的路径
			img_path = path.join(settings.STATIC_ROOT, "/" + img_path)
            # 判断文件是否存在
            if os.path.exists(img_path):
            	with open(imagepath, 'rb') as f:
            		img_data = f.read()
            	return HttpResponse(image_data, content_type="image/png")
            else:
            	# 文件不存在的时候根据自己项目需求去写, 这里就不再写了
            	pass
		except Exception as e:
			# 异常处理我这里就简写了
			print(str(e))

前端访问地址:http://项目地址/img?path=xxx.png
至此就前端就可以正常使用html2canvas截图了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用Vue和html2canvas进行截图时,可能会遇到跨域问题。这是由于浏览器的同源策略所导致的安全限制。当你尝试将html2canvas应用于跨域图片时,浏览器会阻止截图操作。 解决这个问题的一种方法是使用代理服务器。你可以在你的服务器上设置一个代理,将请求发送到目标图片的服务器,并将响应返回给前端。这样,前端的请求就不会涉及跨域问题了。 以下是一个使用代理服务器解决跨域问题的示例代码: 1. 在你的Vue项目中创建一个代理配置文件 `vue.config.js`(如果已经存在,请忽略)。 ```javascript module.exports = { devServer: { proxy: { '/api': { target: 'http://目标图片的服务器地址', changeOrigin: true, pathRewrite: { '^/api': '' } } } } } ``` 2. 在你的Vue组件中使用代理服务器进行截图。 ```javascript import html2canvas from 'html2canvas'; export default { methods: { async captureScreenshot() { try { const canvas = await html2canvas(document.getElementById('target'), { useCORS: true, proxy: '/api' // 使用代理服务器 }); const image = canvas.toDataURL('image/png'); // 处理截图后的操作 } catch (error) { console.error('截图失败:', error); } } } } ``` 在上面的代码中,我们通过设置 `proxy` 选项为 `/api`,将请求发送到代理服务器。然后,代理服务器会将请求转发到目标图片的服务器,并将响应返回给前端。 需要注意的是,你需要将 `http://目标图片的服务器地址` 替换为实际的目标图片服务器地址。 希望以上解决方案能帮助到你!如果你还有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值