node代理解决图片跨域问题

背景

项目中使用<img>标签加载图片(图片资源来自外部AWS、Pinterest等)可以正常使用图片,但在canvas中使用时,<img>加载过的图片就会报跨域问题。

问题分析

1.通过<img>标签加载过的图片,浏览器会将其缓存起来;
2.当通过JavaScript代码再次访问同一个图片并且设置 crossOrigin的跨域属性为 anonymous,浏览器就不会再发起新的请求,而是直接访问缓存的图片。但是由于设置了crossorigin,也就意味着它将要以 CORS 的方式请求,但缓存中的图片显然不是的,所以浏览器直接就拒绝了,连网络请求都没有发起。
3.如果在Chrome devtools中勾选disable cache,js是可以正常请求到图片的,这也进一步验证了第2点。

一些尝试

通过上面的分析,总的说来就是同一个图片资源的crossorigin属性不同,而缓存没有更新导致的,那把crossorigin设置成相同的是不是就OK了?
1.都不设置跨域,<img>不变,canvas中的crossorigin = "undefined"

尽管没有CORS授权也可以在 canvas 中使用图像, 但这样做就会污染(taints)画布。 只要 canvas 被污染, 就不能再从画布中提取数据, 也就是说不能再调用 toBlob(), toDataURL() 和 getImageData() 等方法, 否则会抛出安全错误(security error).
这实际上是为了保护用户的个人信息,避免未经许可就从远程web站点加载用户的图像信息,造成隐私泄漏。 --- 跨域图片资源权限(CORS enabled image)

2.都设置 crossorigin = "anonymous":
可行,需要服务端支持,设置 Access-Control-Allow-Origin: *

解决方案

毕竟这些跨域的图片都是外部资源,也不能直接设置支持跨域,于是我们决定加一个代理服务器。
一个图片原始的url是
https://litb-us-original.s3.amazonaws.com/*****.jpg
经过代理后的url变成
http://pc-cors.elitb.com/proxy?url=https://litb-us-original.s3.amazonaws.com/*****.jpg

const request = require('request');
const fs = require('fs');
const express = require('express');
const router = express.Router();

router.get('/proxy', async (req, res) => {
    const data = req.query;
    const dir = `${__dirname}/images`;
    let url = '', fileName = '';
    // 做一些url及文件名的解析,过程略
    //...
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Credentials', true);
    request(url).pipe(fs.createWriteStream(dir + filename)).on('close', () => {
      res.sendFile(dir + filename, () => {
           fs.unlinkSync(dir + filename)
      })
   });
})
stream

在js代码中,如果我们读取数据或者是打印数据,一般是var 或 let 一个变量,再打印出来,但是这样的方法需要开辟一个新的内存,来保存这个变量,当我们在网页上读取内存较大的文件时(比如视频、图片等),写入写出会极大的占用内存,这时候就需要在node.js中提供给我们的流——stream,stream可以边读边写,这样就可以更好的不占用太多内存。
stream分为四种:readable、writable、duplex、transform
pipe在stream中很常用,用法可以总结为:
readStream.pipe(writeStream);

const fs = require('fs');
const readStream = fs.createReadStream('./data/input.txt');
const writeStream = fs.createWriteStream('./data/output.txt');
readStream.pipe(writeStream);

一些失败的方案
const request = require('request');
const express = require('express');
const router = express.Router();

router.get('/proxy', async (req, res) => {
    const data = req.query;
    let url = '',;
    // 做一些url的解析,过程略
    //...
    request(url, (err, response, data) => {
        const contentType = response?.headers['content-type'];
        res.setHeader('Content-Type', contentType);
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Credentials', true);
        res.send(data);
    })
})
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容