Files
nypc_python_advanced/Web/ProxyImagesDemo/readme.md
iamzhaohaibo 3c4315c40f add Web/ProxyImagesDemo/readme.md.
Signed-off-by: iamzhaohaibo <941604465@qq.com>
2026-01-03 08:57:24 +00:00

121 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 图片代理接口 - README.md
## 项目介绍
这段代码是基于 **Flask 框架**实现的图片代理接口,核心目标是解决前端页面直接加载第三方图片时出现的**跨域访问限制**问题,同时通过模拟浏览器请求头,提高第三方图片资源的获取成功率,避免被第三方服务器拦截拒绝。
## 代码核心作用
1. **跨域绕过**:作为中间代理服务,接收前端本地请求,再由后端向第三方图片服务器发起请求,规避浏览器的同源策略限制,实现图片正常加载。
2. **URL 兼容处理**:自动判断传入的图片地址是否带有 `http://``https://` 协议头,无协议头时自动补充 `https://`,保证请求 URL 有效性。
3. **模拟浏览器请求**:设置符合浏览器规范的 `User-Agent``Referer``Accept` 请求头,伪装成浏览器正常访问,避免被第三方服务器识别为爬虫而拒绝。
4. **图片响应与异常处理**:成功获取图片后,将图片数据以二进制流形式返回给前端,并保留图片原有的 Content-Type请求失败状态码非200或出现异常超时、网络错误等返回 404 错误。
## 前置准备
1. 已安装 Python 3.6 及以上版本。
2. 安装所需的 Python 第三方库Flask 和 requests。
## 安装依赖
打开终端/命令行,执行以下安装命令:
```bash
pip install flask requests
```
## 完整可运行代码
```python
# 导入必要的模块
from flask import Flask, send_file, abort
import requests
from io import BytesIO
# 初始化 Flask 应用
app = Flask(__name__)
@app.route('/proxy-image/<path:image_url>')
def proxy_image(image_url):
"""
图片代理路由,用于绕过跨域限制
"""
try:
# 重新构建完整URL如果需要的话
if not image_url.startswith(('http://', 'https://')):
full_url = 'https://' + image_url.lstrip('/')
else:
full_url = image_url
# 添加请求头来模拟浏览器请求
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Referer': 'https://movie.douban.com/',
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8'
}
# 向第三方图片服务器发起请求设置10秒超时
response = requests.get(full_url, headers=headers, timeout=10)
if response.status_code == 200:
# 将图片内容存入BytesIO二进制流用于send_file返回
image_data = BytesIO(response.content)
# 获取图片原有的Content-Type无则默认image/jpeg
content_type = response.headers.get('Content-Type', 'image/jpeg')
# 以二进制流形式返回图片给前端
return send_file(image_data, mimetype=content_type)
else:
# 第三方服务器返回非200状态码返回404
abort(404)
except Exception as e:
# 捕获超时、网络错误等异常打印错误信息并返回404
print(f"Error fetching image: {e}")
abort(404)
# 启动Flask应用
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
```
## 使用方法
### 步骤1启动代理服务
1. 将完整代码保存为 `image_proxy.py` 文件。
2. 终端/命令行进入该文件所在目录,执行以下启动命令:
```bash
python image_proxy.py
```
3. 启动成功后,终端会显示类似以下信息,说明代理服务已在本地 5000 端口运行:
```
* Serving Flask app 'image_proxy'
* Debug mode: on
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://192.168.x.xxx:5000
```
### 步骤2调用代理接口加载图片
前端页面或直接在浏览器中,通过以下格式的 URL 调用代理接口,即可加载第三方图片:
```
http://127.0.0.1:5000/proxy-image/[第三方图片完整URL或无协议头图片URL]
```
#### 调用示例
1. 第三方图片完整 URL`https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2807886870.jpg`
代理访问地址:
```
http://127.0.0.1:5000/proxy-image/https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2807886870.jpg
```
2. 无协议头图片 URL`img9.doubanio.com/view/photo/s_ratio_poster/public/p2807886870.jpg`
代理访问地址(服务自动补充 `https://`
```
http://127.0.0.1:5000/proxy-image/img9.doubanio.com/view/photo/s_ratio_poster/public/p2807886870.jpg
```
#### 前端使用示例HTML img 标签)
```html
<!-- 直接加载第三方图片可能出现跨域错误 -->
<img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2807886870.jpg" alt="电影海报">
<!-- 通过代理接口加载,规避跨域问题 -->
<img src="http://127.0.0.1:5000/proxy-image/https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2807886870.jpg" alt="电影海报">
```
## 注意事项
1. **超时设置**:当前请求超时时间为 10 秒,若第三方图片服务器响应较慢,可适当调整 `requests.get` 中的 `timeout` 参数值。
2. **请求头调整**`Referer` 字段当前设置为 `https://movie.douban.com/`,若访问其他域名的图片被拦截,可将 `Referer` 修改为对应第三方图片的域名,或删除该字段。
3. **调试模式**:代码中 `app.run` 开启了 `debug=True` 调试模式,生产环境部署时请关闭(改为 `debug=False`),避免泄露敏感信息。
4. **跨域配置(可选)**:若前端与代理服务不在同一端口/域名,需在 Flask 应用中添加跨域支持(安装 `flask-cors` 库,配置 `CORS(app)`),否则前端可能无法正常请求代理接口。
5. **资源限制**:该代理服务仅用于个人开发/测试场景,大规模商用需考虑图片缓存、并发限制、服务器带宽等问题。