IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> http超详细讲解 -> 正文阅读

[网络协议]http超详细讲解

HTTP相关

web浏览器

web server,web是world wide web(万维网)

万维网

万维网是一个大规模的、联机式的信息存储所,简称web

万维网客户端程序 就是 浏览器,服务器返回的万维网文档就是 浏览器窗口显示的页面

CDN

内容分发网络,使用户就近获取资源,提高响应速度

WAF

Web Application Firewall

通过一系列针对http/https的安全策略来专门为web应用提供保护的一款产品

WebService

跨语言和操作系统平台的远程调用技术

http优点

  • 简单、灵活、易于扩展
  • http协议里的核心组成要素没有定死,允许开发者任意定制,给予了浏览器服务器极大信任
  • 应用广泛,环境成熟

http缺点

  • 无状态
  • 明文,用浏览器、Wireshark或者tcpdump抓包后,很容易查看和修改,调试很大的遍历
  • 不安全,可以被监听和被窥探,因为无法判断通信双方的身份,不能判断报文是否被修改过

HTTP协议

定义了浏览器怎么向万维网服务器请求以及服务器怎么把文档传给浏览器

HTTP请求响应过程

请求特征

HTTP报文

  1. 请求行
  2. 请求头
  3. 空行
  4. 实体

四个部分组成,请求行和请求头统称为 header,实体也称 body,实体可以没有

HTTP请求方法

  • GET
  • POST
  • PUT,传输文件,但PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题
  • HEAD,获得响应首部,和GET一样,只是不返回报文主体部分
  • DELETE
  • OPTIONS,询问支持的方法,用来查询针对请求URI指定的资源支持的方法
  • TRACE,追踪路径,让web服务器端将之前的请求通信环回给客户端的方法
  • CONNECT,要求用隧道协议连接代理,要求在与代理服务器通信时建立隧道,实现隧道协议进行TCP通信。主要使用SSL(Secure Sockets Layer),安全套接层TLS(Transport Layer Security),传输层安全协议把通信内容加密后经网络隧道传输

常用就是GET和POST,其他了解即可

GET,POST,PUT,HEAD,DELETE 支持的HTTP协议版本:http1.0,1.1

OPTIONS,TRACE,CONNECT 支持的HTTP协议版本:http1.1

LINK,UNLINE 支持的HTTP协议版本1.0

HTTP版本

HTTP1.0

HTTP1.1

HTTP2.0

image-20211010152336519

HTTP标头

HTTP缓存机制

HTTP内容协商

HTTP是应用层协议,数据达到之后需要告诉应用程序这是什么数据,当然不告诉应用这个是哪种类型的数据,应用也可以通过不断尝试来判断,但这种方式低效,而且很大几率检查不出文件类型

浏览器需要告知服务器自己希望能够接收什么样的数据,需要什么样的压缩格式;而服务器需要告诉客户端自己能提供什么

具体标头查看HTTP标头

HTTP认证

HTTP提供了用于访问控制和身份认证的功能

认证

image-20211005161028054

代理认证

image-20211005161456070

响应:

WWW-Authenticate: <type> realm=<realm>
Proxy-Authenticate: <type> realm=<realm>

<type>是认证协议,Basic是最普遍使用的

realm用于描述保护区域或指示保护范围, 例如:Access to the staging site(访问登陆站点)等,这样用户就可以知道他们要访问哪个区域

认证协议:

  • Basic,base64编码的凭据
  • Bearer,承载令牌来访问受OAuth2.0保护的资源
  • Digest,Firefox仅支持md5哈希,以获得SHA加密支持
  • HOBA
  • Mutual
  • AWS4-HMAC-SHA256

请求:

Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

关于Base64 具体查看编解码和加解密

HTTP CORS跨域

Cross-Origin Resource Sharing(CORS),跨域资源共享

http://Example.com:80
http://example.com

端口一致,Windows和Mac OS X系统的URL不区分大小写,UNIX和Linux系统区分大小写

同源策略

协议,主机(域名),端口一样

处于安全的因素,浏览器限制了从脚本发起跨域的HTTP请求,XMLHttpRequest和其他的Fetch接口会遵循同源策略。也就是说使用这些API的应用程序想要请求相同的资源,那么他们应该具有相同的来源,除非来自其他来源的响应包括正确的CORS标头也可以

跨域请求

跨域资源共享通过 添加新的HTTP标头来工作,这些标头允许服务器描述允许从哪些来源从web浏览器读取信息。另外,对于可能导致服务器数据产生副作用的HTTP请求方法(尤其是GET或者具有某些MIME类型POST方法意外HTTP方法),该规范要求浏览器 预检请求,使用HTTP OPTIONS请求方法从服务器请求受支持的方法,然后再服务器批准后发送实际请求。服务器还可以通过客户端是否应与请求一起发送凭证(例如Cookies和HTTP身份验证

跨域请求,可能会从下面几种请求中发出

XMLHttpRequest是什么?所有的现代浏览器都有一个内置的XMLHttpRequest对象,这个对用于从服务器请求数据

  • 更新网页无需重新刷新页面
  • 页面加载后从服务器请求数据
  • 页面加载后从服务端获取数据
  • 在后台将数据发送到服务器

使用XMLHttpRequest(XHR)对象与服务器进行交互,在AJAX异步编程中使用广泛

Fetch api是什么?

Fetch 是浏览器提供的原生 AJAX 接口。使用 window.fetch 函数可以代替以前的 $.ajax$.getJSON$.post

我们知道 jQuery.ajax 是使用 XMLHttpRequest 对象来发送异步请求的.Fetch就是浏览器帮你把 jQuery.ajax 给实现了,以后大家都是用 fetch 来发送异步请求就好了

fetch特点

  1. 基于 Promise

  2. 不需要依赖第三方库,就可以优雅地使用 AJAX

Web字体(用于CSS中@font-face中的跨域字体使用),以便服务器可以部署TrueType字体,这些字体只能由允许跨站点加载和使用的网站的使用

使用drawImage()绘制到画布上的图像/视频帧

图片的CSS形状

简单请求

简单请求不会触发CORS预检,满足以下所有条件的请求

  • 允许的方法 GETHEADPOST

  • 除了用户代理自动设置的标头()外,唯一手动设置的标头是Fetch规范将其定义为CORS安全列出的请求标头
    Accept
    Accept-Language
    Content-Type(application/x-www-form-urlencode,multipart/form-data,text/plain)
    DPR
    Downlink
    Save-Data
    Viewport-Width
    Width

  • 没有在请求中使用任何XMLHttpRequestUpload对象上注册时间侦听器,

  • 请求中未使用ReadableStream对象

image-20211011231436494

预检请求

预检请求首先通过OPTIONS方法向另一个域上的资源发送HTTP请求,用来确定实际请求是否可以安全的发送。跨站点这样被预检

image-20211011231413065

带凭证的请求

XMLHttpRequestFetchCORS最有趣的功能:能够发出知道HTTP Cookie 和 HTTP身份验证的凭证请求。默认情况下,在跨站点XMLHttpRequestFetch调用中,浏览器不发送凭据

调用XMLHttpRequest对象构造函数时必须设置一个特定的标志

withCredentials = true

image-20211011232603532

跨域HTTP响应标头

  • Accept-Control-Allow-Origin
  • Accept-Control-Allow-Credentials
  • Accept-Control-Allow-Headers
  • Accept-Control-Allow-Methods
  • Accept-Control-Expose-Headers
  • Accept-Control-Max-Age
  • Accept-Control-Request-Headers
  • Accept-Control-Request-Method
  • Origin

例子:

Access-Control-Allow-Origin

如果指定单个来源,而不是 *,需要指定Vary:Origin

Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin

Access-Control-Allow-Headers

响应预检请求,除了CORS安全列出的标头外,还可以

  • 自定义标头
Access-Control-Allow-Headers: X-Custom-Header
  • 多个标头
Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests

Accept-Control-Max-Age

预检请求可以缓存多长时间

Accept-Control-Max-Age: 600

Accept-Control-Allow-Credentials


Accept-Control-Expose-Headers

该响应标头表明哪些标头可以作为响应的一部分公开。默认情况下,仅公开6个CORS安全列出的响应标头,分别是

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma
公开自定义标头
Accept-Control-Expose-Headers: X-Kuma-Revision

在不是凭证请求中,使用通配符,但不会空开Authorization,需要自己加
Accept-Control-Expose-Headers: *, Authorization

HTTP条件请求

对于安全的方法,像是GET、用于请求文档的资源,仅当条件请求的条件满足时返回文档资源

什么是安全的方法?

对于HTTP来说,就是不会改变服务器状态的方法。In a words,方法是只读操作,就是安全方法

GET、HEAD、OPTIONS是幂等的,安全的;但是PUT、DELETE是幂等的,但不安全

幂等性:如果相同的客户端发送一次或者多次HTTP请求会得到相同的结果

对于非安全方法。像是PUT,只有原始文档与服务器上存储的是一样的,才可以使用条件请求来传输文档(PUT方法通常用来传输文件,就像FTP协议的文件上传一样)

If-Match

请求资源的时候用到,与服务器上的ETag的值对比,防止丢失更新,两者一样则返回412

If-None-Match

在http缓存中使用到。具体参考http缓存机制

If-Modified-Since

在http缓存中使用到。具体参考http缓存机制

If-Range

如果满足条件,时间或者ETage,则返回资源

If-Range: Wed, 21 Oct 2015 07:28:00 GMT
If-Range: bfc13a64729c4290ef5b2c2730249c88ca92d82d

If-Unmodified-Since

服务器只有在给定日期之后没有对其进行修改时,服务器才会返回资源

If-Unmodified-Since: Wed, 21 Oct 2015 07:28:00 GMT

以下3个例子:

http缓存机制

断点续传

通过乐观锁避免丢失更新

HTTP Cookie

作用

  • 会话管理:登录,购物车,游戏得分或者服务器应该记住的其他内容
  • 个性化:偏好设置,主题或其他设置
  • 追踪:记录和分析用户行为

Cookie曾经用于一般的客户端存储。是合法的,因为他们是客户端上存储数据的唯一方法。如今,建议使用现代存储API。Cookie随每个请求一起发送,因此他们可能会降低性能(尤其是对于移动数据连接而言)。客户端存储的现代API是Web存储APIIndexedDB

HTTP/2.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

随着对服务器的每个新请求,浏览器将使用Cookie头将所有以前存储的Cookie发送给服务器

GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

Cookie主要分为三类,会话Cookie永久CookieCookie的Secure和HttpOnly标记

会话Cookie

上面的例子就是会话Cookie,因为没有设置Expires或Max-Age。客户端关闭Cookie就会删除

永久Cookie

Set-Cookie:id=a3fWa;Expires=Wed, 21 Oct 2015 07:28:00 GMT;

到设置的时间之后才会过期

Cookie的HttpOnly

安全的cookie需要经过https协议通过加密的方法发送到服务器。即使时安全的,也不应该将敏感信息存储在cookie中,因为他们本质上是不安全的,并且此标志不能提供真正的保护

HttpOnly

  • 会话cookie中缺少HttpOnly属性会导致攻击者可以通过程序(JS脚本、Applet等)获取到用户的cookie信息,造成用户cookie信息泄露,增加攻击者的跨站脚本攻击威胁
  • HttpOnly是微软对cookie做的扩展,该值指定cookie是否可以通过客户端脚本访问
  • 如果在cookie中没有设置HttpOnly属性为true,可能导致cookie被窃取。窃取的cookie可以包含标识站点用户的敏感信息,如ASP.NET会话ID或Forms身份验证凭证,攻击者可以传播窃取的cookie,以便伪装成用户获取敏感信息,进行跨站脚本攻击等

设置了HttpOnly为true之后,js脚本将无法读取到cookie信息,有效防止XSS攻击全称Cross SiteScript,跨站脚本 攻击

//设置多个cookie
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");
response.addHeader("Set-Cookie", "timeout=30; Path=/test; HttpOnly");

//设置https的cookie
response.addHeader("Set-Cookie", "uid=112; Path=/; Secure; HttpOnly");

cookie返回给客户端

@GetMapping("/change-username")
public String setCookie(HttpServletResponse response) {
    // 创建一个 cookie
    Cookie cookie = new Cookie("username", "Jovan");
    //设置 cookie过期时间
    cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
    //添加到 response 中
    response.addCookie(cookie);

    return "Username is changed!";
}

或者用@CookieValue

@GetMapping("/")
public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {
    return "Hey! My username is " + username;
}

springboot中获取cookie

@GetMapping("/all-cookies")
public String readAllCookies(HttpServletRequest request) {

    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        return Arrays.stream(cookies)
                .map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", "));
    }

    return "No cookies";
}

Cookie的作用域

DomainPath标识定义了cookie的作用域,即Cookie应该发送给哪些URL

Domain标识指定了哪些主机可以接受Cookie,如果不指定,默认为当前主机(不包含子域名),如果指定了Domain,则一般包含子域名

例如,设置Domain=mozilla.org,则Cookie也包含在子域名中developer.mozilla.org

例如,设置Path=/docs,则一下地址都会匹配

  • /docs
  • /docs/web/
  • /docs/web/http

XSS

什么是XSS

跨站脚本攻击Cross Site Scripting,为了和层叠样式表CSS区分,将它缩写为XSS

XSS跨站脚本攻击(Cross Site Scripting),的本质是攻击者在web页面插入恶意的script代码(这个代码可以是JS脚本、CSS样式或者其他意料之外的代码),当用户浏览该页面之时,嵌入其中的script代码会被执行,从而达到恶意攻击用户的目的。比如读取cookie,session,tokens,或者网站其他敏感的网站信息,对用户进行钓鱼欺诈等。比较经典的事故有:

2011年6月28日,新浪微博被XSS攻击,大量用户自动转发微博、私信。自动关注用户,大量用户被莫名其妙地控制。因为可以使用JS代码代替用户单击按钮发送请求,所以损坏非常大

危害

  • 通过 document.cookie 盗取 cookie中的信息
  • 使用 js或 css破坏页面正常的结构与样式
  • 流量劫持(通过访问某段具有 window.location.href 定位到其他页面)
  • dos攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法用户无法得到服务器响应。并且通过携带过程的 cookie信息可以使服务端返回400开头的状态码,从而拒绝合理的请求服务
  • 利用 iframeframe、XMLHttpRequest或上述 Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作,并且攻击者还可以利用 iframe,frame进一步的进行 CSRF 攻击
  • 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
https://www.cnblogs.com/54chensongxia/p/11643787.html

流量劫持

是利用各种恶意软件,木马修改浏览器、锁定主页或不停弹出新窗口等方式,强制用户访问某些网站,从而造成用户流量损失的情形

Hosts劫持

hosts文件是一个没有扩展名的文件,通常的路径在C:\Windows\system32\drivers\etc\文件夹内。作用是加快域名解析,尤其是经常访问的网站,用户可以配置映射关系

例如:

::1是ipv6的地址,ipv4是127.0.0.1

127.0.0.1 xxx.com表示xxx.com网站被劫持到本地

域名劫持

关键词劫持

百度搜索某网站关键词,搜索后的结果是正确的,但是点击进去却跳转到别的非法网站

SEO

LSP劫持

混合型劫持

DNS劫持

当别人访问了xxx1.com的时候域名还是他原来的域名,但是内容确实劫持的内容

dos攻击

iframe、frame

少用iframe

CSRF

跨域请求伪造

攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账

image-20211016161617997

从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  • 登录受信任网站A,并在本地生成Cookie。
  • 在不登出A的情况下,访问危险网站B。
    看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了…)

防御CSRF

验证Referer字段

A网站会验证Referer值,如果是自己域名开头的,接受请求;否则拒绝

虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不安全。

如果使用ie6,则有方法篡改Referer值

在请求地址中添加token并验证

token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。对于 GET 请求

http://url?csrftoken=tokenvalue

对于 POST 请求,要在 form 的最后加上

<input type="hidden" name="csrftoken" value="tokenvalue"/>

要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,在编码时手动添加 token

还有一个缺点是难以保证 token 本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以在上面发布自己个人网站的地址。由于系统也会在这个地址后面加上 token,黑客可以在自己的网站上得到这个token,并马上就可以发动 CSRF 攻击

为了避免这一点,系统可以在添加 token 的时候增加一个判断,如果这个链接是链到自己本站的,就在后面添加 token,如果是通向外网则不加

不过,即使这个 csrftoken 不以参数的形式附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击

HTTP头中自定义属性并验证

通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去

然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便

HTTPS

http天生明文传输的特性,在传输过程中,任何人都有可能从中截获、修改或者伪造请求发送,所以不安全。在HTTP的传输过程中不会验证通信方的身份,因此HTTP信息交换的双方可能会遭到伪装;接收方和发送方并不会验证报文的完整性,为了解决以上问题HTTPS应运而生

HTTP + SSL / TLS = HTTPS,默认端口443

HTTPS做了什么

  • 加密encryption
  • 数据一致性,传输中不会被窃听者修改,保证用户发的是什么,服务器就收到什么
  • 身份认证,是指确认对方的真实身份,也就是证明你是你,它可以防止中间人攻击并建立用户信任

中间人攻击

中间人攻击是指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制

有一个前提,需要截获客户端与服务端通信的线路

https://www.jianshu.com/p/a4d719bdf7ce

SSL/TLS

TLS(Transport Layer Security)是SSL(Secure Socket Layer)的后续版本,它们是用于在互联网两台计算机之间用于身份验证加密的一种协议

SSL/TLS通过将称为X.509证书的数字文档将网站和公司的实体信息绑定到加密密钥来进行工作

X.509公开密钥证书的标准格式,这个文档将加密密钥与(个人或组织)进行安全的关联

X.509主要应用:

  • SSL/TLS和HTTPS用于经过身份验证和加密的Web浏览
  • 通过S/MIME协议签名和加密的电子邮件
  • 代码签名:它指的是使用数字证书对软件应用程序进行签名以安全分发和安装的过程

通过使用由知名公共证书颁发机构(例如SSL.com)颁发的证书对软件进行数字签名,开发人员可以向最终用户保证他们希望安装的软件是由已知且受信任的开发人员发布;并且签名后未被篡改或损害

  • 还可用于文档签名

  • 还可用于客户端认证

  • 政府签发的电子身份证

    https://www.ssl.com/article/pki-and-digital-certificates-for-government/
    

具体参考密码学中的 现代密码学

HTTPS工作原理

Cookie和Session的区别

https://blog.csdn.net/chen13333336677/article/details/100939030

JSON Web Token和Session Cookie的对比

UDP

TCP

TCP三个握手和四次挥手

TCP 和 UDP的区别

地址栏输入URL发生了什么

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-10-20 12:51:43  更:2021-10-20 12:51:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年7日历 -2024/7/1 10:54:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码