请求HTTP链接的图片等资源被自动变成HTTPS请求的问题解决(顺便可以解决图片防盗链)

news/2024/10/9 11:36:24/
http://www.w3.org/2000/svg" style="display: none;">

文章目录

      • 问题现象
      • 问题根本原因
      • 常规问题解决办法
        • 非Chrome浏览器:控制CSP协议
          • 对HTML页面处理
          • nginx配置中处理
        • Chrome浏览器本地处理方式
      • Chrome浏览器通用解决办法(服务器端无法控制新版Chrome这种行为,只能曲线救国--顺便可以解决图片防盗链
        • 网页的网站使用 http 域名
        • 代理服务器
        • 使用CORS:fetch API请求图片

问题现象

Chrome浏览器中,在采用 https 协议的页面当中,当以<img src="http://xxx">这样的方式去请求 http 资源的时候,原本属于 http 协议的资源地址将会被转换成为 https。

举例:

假设你有一个网页,页面地址是https://www.example.com。(注意:网页是一个 https 开头的网址

页面中有如下的图片引用代码:(注意:src是一个 http 开头的网址

<img src="http://img.another-example.com/image.jpg">

在最新版本的Chrome浏览器中,当加载这个采用 HTTPS 协议的网页时,浏览器会将图片的请求地址http://img.another-example.com/image.jpg自动转换为https://img.another-example.com/image.jpg进行请求。

如果img.another-example.com这个服务器没有配置好 HTTPS 服务设置不支持 HTTPS,那么这个图片会因为无法通过安全验证而无法正常加载,浏览器会不能显示该图片,并在控制台中输出相关的安全错误信息。

问题根本原因

Chrome浏览器最新版本(从某个版本以后的所有新版本)在请求图片等资源时都会自动将HTTP请求升级为HTTPS请求,以提高安全性。且无法通过服务器端(例如HTTP Header等手段)控制这种行为。

常规问题解决办法

非Chrome浏览器:控制CSP协议

对于非Chrome浏览器,可以通过控制CSP协议的方式来改变在请求图片等资源时自动将HTTP请求升级为HTTPS请求的行为。

具体来讲,有2种方式:

对HTML页面处理

可以在HTML页面的<header>标签中添加如下代码:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
nginx配置中处理

在 nginx.conf 中的server块下添加如下配置:

        # 对xxx路径的页面,允许不安全的请求(即允许HTTP资源加载)location /xxx/ {add_header Content-Security-Policy "default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * http://pal3.roogames.com/  data: 'unsafe-inline' 'unsafe-eval'; connect-src *; frame-src *; font-src * data:; style-src * 'unsafe-inline'";add_header Upgrade-Insecure-Requests off;}
Chrome浏览器本地处理方式

为了清除Chrome浏览器中特定域名的HSTS(HTTP Strict Transport Security)策略,可以按照以下步骤操作:

  1. 在Chrome浏览器的地址栏中输入 chrome://net-internals/#hsts,然后按Enter键进入Chrome的网络内部设置页面。

  2. 在页面的“Delete domain security policies”部分,输入你要删除HSTS策略的域名(只需输入“http://”后面的域名部分,例如 example.com),然后点击“Delete”按钮以删除该域名的HSTS策略。

  3. 接下来,你可以在“Query domain”部分输入相同的域名,以测试HSTS策略是否已被成功删除。如果删除成功,你应该不会看到有关该域名的HSTS记录。

  4. 如果上述步骤未能解决问题,尝试清除浏览器缓存。打开Chrome浏览器的清除浏览数据功能(通常可通过按Ctrl + Shift + Delete组合键快速访问),选择清除缓存和Cookies,然后点击“清除数据”。完成清理后,重启浏览器再次尝试访问该网站。

Chrome浏览器通用解决办法(服务器端无法控制新版Chrome这种行为,只能曲线救国–顺便可以解决图片防盗链

http__60">网页的网站使用 http 域名

包含 <img src="http://xxx"> 的网页如果是 http 协议,那么就可以避免该问题。尤其是使用不带协议头的地址来请求资源时,会默认添加当前网页的协议,例如:<img src="//img.another-example.com/image.jpg">

代理服务器

例如如下的nginx配置:

http {upstream another_example_com {server img.another-example.com:80;}# 主要的Nginx服务器配置server {listen 443 ssl;  # 监听443端口并启用SSLserver_name proxy2img.example.com;  # 你的主域名# SSL证书配置ssl_certificate /etc/nginx/ssl/example.com.crt;ssl_certificate_key /etc/nginx/ssl/example.com.key;# 代理服务器配置location / {# 主要的代理配置proxy_pass http://another_example_com;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;# 重定向所有HTTP请求到HTTPSif ($scheme != "https") {return 301 https://$host$request_uri;}}# 特殊的代理配置用于处理图片location ~* ^.+\.(jpg|jpeg|gif|png)$ {proxy_pass http://another_example_com;proxy_set_header Host img.another-example.com;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Accept-Encoding "";proxy_cache_bypass $http_pragma;}}
}

在网页中可以将http的资源目标地址替换为本代理网站,或者使用以下js脚本来实现自动转发:

self.addEventListener('fetch', event => {if (event.request.url.includes('example.com/images/')) {event.respondWith(fetch(event.request.url.replace('example.com', 'your-proxy-server.com')));} else {event.respondWith(fetch(event.request));}
});

通过该方式还有一个优点时:一般不会受到目标图片网站的防盗链等机制的干扰。

使用CORS:fetch API请求图片

CORS是一种安全机制,用于控制一个域下的Web页面能否访问另一个域下的资源。根据同源策略(Same-Origin Policy),Web浏览器默认不允许从一个域加载另一个域的数据,除非后端服务器明确允许这种跨域请求。

CORS通过在HTTP响应头中设置特定的字段来指示浏览器是否允许跨域请求。这些字段包括但不限于:

  • Access-Control-Allow-Origin: 用于告诉浏览器允许哪些源(即域名)进行跨域请求。
  • Access-Control-Allow-Methods: 指定允许的HTTP方法(如GET、POST等)。
  • Access-Control-Allow-Headers: 指定允许的请求头字段。
  • Access-Control-Allow-Credentials: 是否允许携带认证信息(如Cookie或HTTP认证信息)。

开启CORS支持后,通过fetch API请求图片资源,然后将获取到的图片数据转换为Blob对象,并创建一个URL来引用这个Blob对象,最后将这个URL设置为HTML <img> 元素的 src 属性,从而在页面上显示图片。

示例代码如下:

fetch('https://example.com/images/my-image.jpg').then(response => response.blob()).then(blob => {const imageUrl = URL.createObjectURL(blob);document.getElementById('image').src = imageUrl;});

Fetch API允许你在请求中自定义HTTP头,包括Referer头,这可以帮助绕过图片防盗链机制

// 设置请求头
const headers = new Headers({'Referer': 'https://your-allowed-domain.com','User-Agent': 'Mozilla/5.0 (Your-Browser-Info)'
});// 创建请求选项
const options = {method: 'GET',headers: headers
};// 发起请求
fetch('https://example.com/images/my-image.jpg', options).then(response => {// 检查响应状态if (!response.ok) {throw new Error('Network response was not ok');}return response.blob();}).then(blob => {const imageUrl = URL.createObjectURL(blob);document.getElementById('image').src = imageUrl;}).catch(error => {console.error('There has been a problem with your fetch operation:', error);});

http://www.ppmy.cn/news/1526934.html

相关文章

leetcode 605.种花问题

只说注意点和处理边界问题。 题目本身很简单&#xff0c;只需要遍历数组即可。但是&#xff0c;需要注意边界的处理问题。 如果n0&#xff0c;那么这个时候是不需要插进花的&#xff0c;所以是true&#xff1b; 如果花坛中的数目是0&#xff0c;那么就不行&#xff0c;返回f…

素数个数[中秋快乐~]

题目描述 编程求 2 &#xff5e; n (包括 n)中有多少个素数。 输入格式 输入 n(2≤n≤50000)。 输出格式 素数个数。 输入数据 1 10输出数据 1 4代码 #include<bits/stdc.h> using namespace std; int main(){int n,ans0;cin>>n;for(int i2;i<n;i){int…

Oracle中VARCHAR和VARCHAR2的区别

Oracle中VARCHAR和VARCHAR2的区别 VARCHAR2 默认类型&#xff0c;VARCHAR2是Oracle中最常见的可变长度字符串类型VARCHAR2不区分NULL和空字符串&#xff0c;这意味着NULL和空字符串在VARCHAR2类型中被视为相同的值最大长度为4000字节&#xff08;从Oracle 12c开始&#xff0c…

Git:版本控制工具介绍

目录 全文概要版本控制工具介绍版本控制系统的概念**版本控制系统的历史****版本控制系统的分类****本地版本控制系统****集中式版本控制****分布式版本控制系统** Git 介绍Git 概念Git 与 SVN 对比**SVN的记录方式****Git 的记录快照** Git 安装Git 安装Bash、CMD与GUIGit 的配…

gRPC etcd 服务注册与发现、自定义负载均衡

本文首发在这里 考虑这种常见情景&#xff1a;服务多开&#xff0c;正常连接采用轮询负载均衡&#xff0c;但若服务有状态&#xff0c;重连则需进入之前的服务 本文其实主要在讨论以下两篇官方文档 gRPC naming and discoveryCustom Load Balancing Policies 实现依赖即将废…

红外成像人员检测数据集

红外成像人员检测数据集YOLO格式介绍 红外成像技术是一种非接触式的温度测量技术&#xff0c;通过探测物体发出的红外辐射来生成图像。这种技术在人员检测领域有着广泛的应用&#xff0c;尤其是在夜间监控、安全防范、医疗诊断、环境监测等方面。本文将详细介绍一个红外成像人…

小程序面试题八

一、微信小程序如何处理页面间的数据通信&#xff1f; 微信小程序处理页面间的数据通信&#xff0c;可以采用多种方式&#xff0c;这些方法根据具体需求和场景的不同而有所选择。以下是几种常见的页面间数据通信方式&#xff1a; 1. URL 传递参数 适用场景&#xff1a;适用于…

‌内网穿透技术‌总结

内网穿透是一种网络技术&#xff0c;通过它可以使外部网络用户访问内部网络中的设备和服务。一般情况下&#xff0c;内网是无法直接访问的&#xff0c;因为它位于一个封闭的局域网中&#xff0c;无法从外部访问。而通过内网穿透&#xff0c;可以将内部网络中的设备和服务暴露在…