Skip to content

Commit 07375ce

Browse files
committed
✨ fix: Add a temp solution for canvas
1 parent 8e38563 commit 07375ce

File tree

4 files changed

+109
-1
lines changed

4 files changed

+109
-1
lines changed

docs/e2e/basic/canvas.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Canvas 解析
3+
order: 30
4+
---
5+
6+
## 基本 Canvas 解析
7+
8+
<code src="./demos/CanvasBasic.tsx" />
9+
10+
## Canvas 跨域图片解析
11+
12+
<code src="./demos/CanvasCors.tsx" />
13+
14+
### 跨域问题说明
15+
16+
某些 Canvas 由于绘制了跨域图片,因此无法使用 `toDataURL` 方法 ,会报错:
17+
18+
```
19+
Tainted canvases may not be exported
20+
```
21+
22+
### 解决方案
23+
24+
这个时候解决方案有两种:
25+
26+
#### 你可以控制 `img`
27+
28+
如果你可以控制提供 canvas 渲染的 img 节点,那一切都行相对容易,给 img 节点添加上 `crossOrigin` 属性即可
29+
30+
```html
31+
<img src="otherdomain.com" crossorigin="Anonymous" />
32+
33+
<!-- Or with Javascript -->
34+
<script>
35+
var image = new Image();
36+
image.crossOrigin = "Anonymous";
37+
...
38+
</script>
39+
```
40+
41+
不过这样的前提是你的图片服务器请求头中必须带有 `Access-Control-Allow-Origin "*"` ,否则就会提示跨域问题
42+
43+
PS: 如果无法处理图片服务器,可以利用 `cors-anywhere` 进行中转,或自行搭建代理
44+
45+
```
46+
https://cors-anywhere.herokuapp.com/${url}
47+
```
48+
49+
#### 你不能控制 `img`
50+
51+
如果你没法拿到 image 的 src 只能通过禁用 chrome 的同源策略才能解决
52+
53+
禁用方法(以 macOS 为例):
54+
55+
macOS:
56+
57+
```bash
58+
open -a "/Applications/Google Chrome.app" --args \
59+
--disable-web-security \
60+
--user-data-dir=/Users/{your account name}/chromeTempData/
61+
```
62+
63+
第一次打开如下图,就说明已经禁用同源策略了: ![](https://gw.alipayobjects.com/zos/antfincdn/hokkCFfJB9/1a018628-ae13-4fbc-82c4-eac5626e33c6.png)
File renamed without changes.

docs/e2e/basic/demos/CanvasCors.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React, { useEffect } from 'react';
2+
import { useElements, TestLayout } from '@e2e-utils';
3+
4+
/**
5+
*
6+
*/
7+
export default () => {
8+
const { elements, ref } = useElements();
9+
10+
useEffect(() => {
11+
const canvas = ref.current;
12+
const ctx = canvas.getContext('2d');
13+
const image = document.getElementById('source');
14+
15+
image!.onload = function () {
16+
ctx.drawImage(image, 0, 0);
17+
};
18+
}, []);
19+
return (
20+
<TestLayout elements={elements}>
21+
<div>
22+
<canvas ref={ref} id="canvas" width="500" height="500" />
23+
</div>
24+
<div style={{ display: 'none' }}>
25+
<img
26+
id="source"
27+
src="https://wx2.sinaimg.cn/large/4176adebgy1ge52j9bku3j20dl7pse2q.jpg"
28+
alt={'image'}
29+
/>
30+
</div>
31+
</TestLayout>
32+
);
33+
};

src/parser/canvas.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Bitmap } from '../model';
22
import { isCanvasNode } from '../utils/nodeType';
3+
import { errorBase64Url } from '../utils/image';
34

45
/**
56
* 将Canvas 解析为图片
@@ -8,8 +9,19 @@ import { isCanvasNode } from '../utils/nodeType';
89
export const parseCanvasToBitmap = (canvas: HTMLCanvasElement) => {
910
if (!isCanvasNode(canvas)) return;
1011
const { width, height, y, x } = canvas.getBoundingClientRect();
12+
let url;
13+
try {
14+
url = canvas.toDataURL();
15+
} catch (e) {
16+
const errMsg = e.toString();
1117

12-
const url = canvas.toDataURL();
18+
// 存在跨域问题
19+
if (errMsg.includes('Tainted canvases may not be exported.')) {
20+
// 跨域问题的显示图片
21+
url =
22+
'data:image/png;base64,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';
23+
} else url = errorBase64Url;
24+
}
1325

1426
const bitmap = new Bitmap({ url, width, height, y, x });
1527
bitmap.mapBasicInfo(canvas);

0 commit comments

Comments
 (0)