web前端生成图片之探索踩坑
前段时间,产品和运营整了个非常变态的需求,要求将一个活动页面输出为图片,然后用户进行分享
开始以为是用户自己手动截图分享,没想到后来不是,细思极恐,感叹需求之变态。
从网上找了N个方案,最后确定使用 html2canvas 基本可实现(http://html2canvas.hertzen.com/),下面开始踩坑。
html2canvas 的原理在于利用封装的js将html的显示输出转化为canvas,根据页面的复杂度,可能会遇到一些问题。
截图模糊
解决原理就是讲canvas画布的width和height放大两倍
后来了解canvas的时候,其写法不同于css的宽高设置,因为css里的只是展示画布显示的大小,不像canvas是真正的图画分辨率的大小
/*图片跨域及截图模糊处理*/
let shareContent = domObj,//需要截图的包裹的(原生的)DOM 对象
width = shareContent.clientWidth,//shareContent.offsetWidth; //获取dom 宽度
height = shareContent.clientHeight,//shareContent.offsetHeight; //获取dom 高度
canvas = document.createElement("canvas"), //创建一个canvas节点
scale = 2; //定义任意放大倍数 支持小数
canvas.width = width * scale; //定义canvas 宽度 * 缩放
canvas.height = height * scale; //定义canvas高度 *缩放
canvas.style.width = shareContent.clientWidth * scale + "px";
canvas.style.height = shareContent.clientHeight * scale + "px";
canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
let opts = {
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
logging: false, //日志开关,便于查看html2canvas的内部执行流程
width: width, //dom 原始宽度
height: height,
useCORS: true // 【重要】开启跨域配置
};
html2canvas(shareContent,opts).then()
the operation is insecure
canvas.toDataURL 报错 the operation is insecure
canvas.toDataURL(type, encoderOptions);语法
配置如:canvas.toDataURL("image/png", 0.7);
参数type指定图片类型,如果指定的类型不被支持则以默认值image/png替代;
encoderOptions(第二个参数)可以为image/jpeg或image/webp类型的图片设置图片质量,取值0-1,超出则以默认值0.92替代。
html2canvas在微信中base64码为空
在微信中或者可以说在移动端浏览器里,canvas.toDataURL不成功。canvas.toDataURL(type) 得到空的 data:;
引发这个问题的操作可能有2中,1、canvas被污染,2、生成图片过大,base64码有长度限制
不可见的元素截图后是空白
没法截图看不见的,比如opacity为0的东西,或者visibility为hidden的,更别说display:none了。
解决方法是让canvas部分隐藏到后边。最终选择方案,层级设为-1,上一层的把他盖住。前提是上一层要又一个可以设置的背景色,能把他盖住不被世人看到
html2canvas结合微信里的长按存图功能
先用html2canvas拿到一个html转为canvas的base64码,
再在页面建立一个img元素,src=base64码,插入dom中,盖在所有元素的最上方(或者需要用户长按保存的地方),opacity设置为0。
然后用户就长按保存,存下来的就是事先准备好的覆盖在那里的那个不可见得透明图。
事实证明,图片透明不可见覆盖在页面上边,微信里是可以存图的。
html2canvas 截图跨域
图片跨域时报错现象

这个时候你要去看图片的header头有没有这个:
看图片本身是否允许跨域访问:

上边这个是一个允许的图片。下边这个不允许,就截取不到。

主要是用于解决了本次问题的地方:useCORS:true 这个参数很重要,没有配置的话,依旧是不能解决问题的;
根据现有的解决方案大致有两种:
(1).在跨域的服务器上设置header设置为允许跨域请求。 在服务器上设置header设置允许跨域请求
(2).借助代理脚本获得外域图片的 base64 编码后的字符串,本文未采用。
作者:旧旧的 <393210556@qq.com> 解决问题的方式,就是解决它一次
web前端生成图片之探索踩坑的更多相关文章
- [Web 前端] React Router v4 入坑指南
cp from : https://www.jianshu.com/p/6a45e2dfc9d9 万恶的根源 距离React Router v4 正式发布也已经过去三个月了,这周把一个React的架子 ...
- 【web】docker复现环境踩坑
在先知看到有师傅发了个学习 P 牛的代码审计的文章,在 github 上下下来复现环境,结果 docker 各种问题,气死 安装 docker-compose:pip install -i https ...
- React Native 环境搭建踩坑
React Native (web Android)环境搭建踩坑(真的是一个艰辛的过程,大概所有坑都被我踩了 官方文档地址 : https://facebook.github.io/react-nat ...
- Web前端开发(基础学习+坑)
0.基本说明 0.内容为课堂所学基本知识,加自己踩过的坑 1.web基本框架:html+css+JavaScript,html为网页骨架,css为网页美化,JavaScript负责页面动态交互,脚本等 ...
- vue.js 踩坑第一步 利用vue-cli vue-router搭建一个带有底部导航栏移动前端项目
vue.js学习 踩坑第一步 1.首先安装vue-cli脚手架 不多赘述,主要参考WiseWrong 的 Vue 爬坑之路(一)-- 使用 vue-cli 搭建项目 2.项目呈现效果 项目呈现网址:w ...
- web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】
http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...
- web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史
秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...
- ASP.NET Web 应用 Docker踩坑历程——续
ASP.NET Web 应用 Docker踩坑历程发表后,也开始使用Docker了,然而发布的过程比较痛苦,经常发生下图的事情: 据说是nuget包还原时发生错误 百度了半天也找不到解决的方法,而发生 ...
- react-router 踩坑记
react-router踩坑分享 背景 辛苦历程 JavaScript动态修改 第一次尝试 第二次尝试 第三次尝试 第四次尝试 总结步骤 其他方案 原理 History 常见的3种History Br ...
随机推荐
- 自动发现项目中的URL,django1版本和django2版本
一.django 1 版本 routers.py import re from collections import OrderedDict from django.conf import setti ...
- Diycode开源项目 TopicContentActivity分析
1.效果预览以及布局分析 1.1.实际效果预览 左侧话题列表的布局是通过TopicProvider来实现的,所以当初分析话题列表就没有看到布局. 这里的话题内容不是一个ListView,故要自己布局. ...
- Spring---浅谈AOP
概念 AOP是Aspect Oriented Programming的缩写,即面向切面的编程.是一种比较新颖的编程思想,也是Spring框架中一个重要的领域. AOP将应用系统分为两个部分:核心业务逻 ...
- P3402 最长公共子序列(nlogn)
P3402 最长公共子序列 题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子 ...
- Spring MVC 使用 HttpServletResponseWrapper 修改返回结果
HttpServletResponseWrapper 是什么? ServletResponse 的包装类,相关设计模式 装饰者模式. 运行环境 jdk 1.7 spring boot 整合的web环境 ...
- loj2045 「CQOI2016」密钥破解
CQOI 板子大赛之 pollard rho #include <iostream> #include <cstdio> using namespace std; typede ...
- ogre3D学习基础19 --- 材质的继承,纹理的滚动与旋转
以上一节为基础,废话不多说. 首先新增一个节点,用于比较显示 //新增一个节点 ent = mSceneMgr->createEntity("Quad"); ent-> ...
- 第一章:前端布局之display属性
css布局学习网站:http://zh.learnlayout.com
- PostgreSQL 数组类型
PostgreSQL 支持表的字段使用定长或可变长度的一维或多维数组,数组的类型可以是任何数据库内建的类型.用户自定义的类型.枚举类型, 以及组合类型.但目前还不支持 domain 类型. 数组类型的 ...
- python中 in, any 和 all用法
in if x == 1 or y == 1 or z == 1: print('passed') if 1 in (x, y, z): print('passed') any if x or y o ...