我们知道,img标签是不会有跨域的问题的,所以我们可以直接在img标签中利用src属性引用其它域中的图片,但是如果出现下面的情况呢?
<img src="http://pics6.baidu.com/feed/5bafa40f4bfbfbed9f8a1ef376c06332aec31f1a.jpeg?token=7de2efd6c5a751773e7b13a244a38d3f&s=2AFA49850013BFDC2A659CA303003043" alt="图片">
我们发现出现了403错误,也就是说,服务器理解我们的请求,但是拒绝为我们服务,这时候该怎么办呢?不慌,下面我们就用服务端的node代理来解决这个问题
目标:在浏览器中输入http://localhost:4000/getPic,显示上面未请求成功的图片
首先,我们用node的http模块,fs模块来获取图片
代码有详细的解释
const http = require("http");
const fs = require('fs')
http.createServer((req, res)=>{
if(req.url === '/') {
res.writeHead(200, {'Content-Type': 'text/plain'})
res.write('Hello World')
res.end()
}
if(req.url === '/getPic') {
let url = 'http://pics6.baidu.com/feed/5bafa40f4bfbfbed9f8a1ef376c06332aec31f1a.jpeg?token=7de2efd6c5a751773e7b13a244a38d3f&s=2AFA49850013BFDC2A659CA303003043'
// 用http的get方法来发送请求
http.get(url, (resonse)=>{
//data 存储图片数据,是二进制流
var data = "";
// 一定要设置encode,否则即使在pic/downImg/中有1.jpg,也是无法显示的
response.setEncoding("binary")
// 当数据到达时会触发data事件
response.on('data', function (chunk) {
data += chunk;
});
// 当数据接收完毕之后,会触发end事件
response.on("end", function() {
// 用fs模块,读取到的图片,放到pic/downImg下,命名为1.jpg
// 这里要注意pic和downImg文件夹事先要存在,否则会报错
fs.writeFile('../pic/downImg/1.jpg',data, 'binary', (err)=>{
if(err) {
res.write('error: ' + err.toString())
res.end()
}else getPic(res) // getPic的作用是把图片返回给浏览器
})
});
}).on("error", function() {
console.log('error')
});
}
}).listen(4000);
console.log('server listening on port 4000')
到目前为止,我们完成了图片的读取,运行了代码,看下downImg里是否有1.jpg
确实有的,接下来我们就要读取这张图片,返回给浏览器了
补上getPic函数
function getPic(res) {
fs.readFile('../pic/downImg/1.jpg', function(err, data){
if(err) {
res.write('error')
}else {
// Content-Type的值一定要和返回数据的类型相匹配,否则浏览器是不能正确解析数据的
res.writeHead(200, {"Content-Type" : "image/jpeg"})
res.write(data)
}
res.end() // 如果end,浏览器会有警告,提醒你请求未结束
})
}
没有设置Content-Type时,在浏览器中呈现的样子
没有end的时候
警告:请求未结束
好了,最后来看下结果吧!