八、浏览器同源策略

上一篇👉: 浏览器垃圾回收机制

文章目录

  • 浏览器同源策略
    • 1.同源策略的定义
    • 2.同源策略的作用
    • 3.同源策略的限制范围
    • 4.解决跨域方案汇总
      • 1.CORS(跨源资源共享)
      • 2.JSONP
      • 3.postMessage 跨域
      • 4.Nginx代理跨域
      • 5.Node.js中间件代理跨域
      • 6.document.domain + iframe
      • 7.Location.hash + iframe
      • 8.window.name + iframe跨域
      • 9.WebSocket协议跨域
    • 5.正向代理与反向代理的区别
      • 正向代理(Forward Proxy)
      • 反向代理(Reverse Proxy)
      • 核心差异
    • 6.Nginx
      • Nginx概念及工作原理
      • 核心特性
      • 架构层次
      • Master Process(主进程)
      • Worker Processes(工作进程)
      • 工作流程

浏览器同源策略

1.同源策略的定义

同源策略(Same-origin policy)是Web浏览器为保护用户信息安全而实施的一种重要安全策略。该策略规定,Web浏览器允许来自同一源的文档或脚本访问彼此的资源,但限制了来自不同源的交互。这里的“源”指的是协议、域名和端口号三者的组合。如果三个要素完全一致,则视为同源;有任何一个不相同,则视为跨域。

2.同源策略的作用

  • 保护用户数据:防止恶意网站读取另一个网站的敏感数据,如Cookies、存储在浏览器中的用户个人资料等。
  • 防止恶意脚本执行:阻止不同源的脚本相互操作,防止恶意脚本注入和执行,保护用户的浏览环境安全。

3.同源策略的限制范围

同源策略主要在以下几个方面实施限制:

  • JavaScript访问权限:禁止脚本读取或修改不同源页面的DOM,也无法向不同源的服务器发送Ajax请求(除非目标服务器明确允许跨域)。
  • Cookie、LocalStorage和IndexedDB访问:禁止脚本访问不同源的这些存储数据,保护用户数据不被非法窃取或篡改。
  • 其他API限制:包括Web Storage、Web Workers、Fetch API等现代Web
    API在内,大多遵循同源策略,限制跨域访问。

4.解决跨域方案汇总

1.CORS(跨源资源共享)

CORS(跨域资源共享)是一种机制,确保了网页可以从不同源(协议、域名、端口)的服务器上获取资源,而不会受到浏览器同源策略的限制。这一机制通过在HTTP请求和响应中加入特定的头部信息来工作,从而允许或拒绝跨域请求。

  • 简单请求
    简单请求的特点是使用了GET、HEAD或POST方法,并且HTTP头部信息限于几个特定字段。这类请求不会触发预检请求(preflight request),浏览器直接发起请求,并在请求头中加入Origin字段,表明请求源。服务器需要在响应中包含Access-Control-Allow-Origin头部,以明确允许的请求源。对于简单请求,服务器至少需要配置Access-Control-Allow-Origin字段。

  • 非简单请求
    包括使用了除GET、HEAD、POST之外的方法(如DELETE、PUT),或POST请求中包含非标准的内容类型、自定义请求头等。这类请求会在正式请求前先发送一个OPTIONS请求作为预检请求,以确认实际请求是否安全可接受。预检请求会携带Origin、Access-Control-Request-MethodAccess-Control-Request-Headers等头部。服务器需响应这些头部对应的允许值,至少包括Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers

  • Cookie处理
    要在CORS请求中携带Cookie,需满足以下条件:

    • 客户端(如通过XMLHttpRequest或Fetch API)需设置withCredentials属性为true,表明请求需要携带凭据(如Cookie)。
    • 服务器响应中必须设置Access-Control-Allow-Credentials为true,表明服务器允许浏览器携带Cookie。
    • Access-Control-Allow-Origin不能设为星号*,而应指定具体的源地址,因为星号不允许与Access-Control-Allow-Credentials: true一起使用。
  • 减少OPTIONS请求
    为了优化性能,可以通过在服务器响应中设置Access-Control-Max-Age头部来缓存预检请求的结果,避免每次请求都发送OPTIONS请求。该值指定了预检请求结果的有效期,单位为秒。

总之,CORS通过一系列HTTP头部的精确控制,实现了安全的跨域数据交互,同时提供了灵活的配置选项以适应不同场景的安全需求和性能优化。

2.JSONP

JSONP(JSON with Padding)是一种跨域数据交互技术,其原理基于浏览器对 <script> 标签的特性和同源策略的绕过。

原理:JSONP利用了浏览器对<script>标签的特殊处理:通过动态创建<script>元素并设置其src属性为包含API请求的URL,由于<script>标签的资源请求不受同源策略限制,因此可以实现跨域数据请求。请求URL中通常包含一个查询参数,用于指定客户端期望调用的回调函数名称。服务器接收到请求后,会将响应数据包裹在这个回调函数中返回,从而在客户端执行并传递数据。

JavaScript实现

<script>// 创建script元素var script = document.createElement('script');script.type = 'text/javascript';// 设置src属性,包含请求URL及回调函数名script.src = 'http://www.example.com/api/data?callback=myCallback';// 将script元素插入页面,触发请求document.head.appendChild(script);// 定义回调函数处理服务器返回的数据function myCallback(data) {console.log(data);}
</script>

服务器响应内容示例:

myCallback({"status": "success", "message": "Hello, World!"});

Vue中使用axios实现JSONP
在Vue项目中,虽然axios本身不直接支持JSONP,但可以通过封装或使用第三方库如vue-jsonp来实现。这里提供一个简化的示例说明如何模拟实现:

// 注意:实际开发中应使用专门的库或封装方法
this.$http.jsonp('http://www.example.com/api/data', {params: {callback: 'myCallback'}
}).then((res) => {console.log(res.data); 
})

后端Node.js示例
后端需要解析请求中的回调函数名,并将响应数据封装进该函数返回。

const http = require('http');
const querystring = require('querystring');const server = http.createServer((req, res) => {let params = querystring.parse(req.url.split('?')[1]);let callback = params.callback;// 假设这是从数据库获取的数据let data = {"status": "success", "data": "Sample Data"};// 构造JSONP响应res.writeHead(200, {'Content-Type': 'application/javascript'});res.end(`${callback}(${JSON.stringify(data)})`);
});server.listen(8080, () => {console.log('Server running on port 8080');
});

JSONP的缺点

  1. 仅支持GET请求:因为数据是通过URL查询参数传递的,这限制了其适用场景,不适合大型数据传输或涉及敏感信息的请求。
  2. 安全性问题:容易受到XSS(跨站脚本攻击)的威胁,恶意脚本可能通过构造特殊的回调函数名注入执行。
  3. 无错误处理机制:相比现代的CORS等技术,JSONP缺乏标准化的错误处理流程,调试和错误报告较为困难。

3.postMessage 跨域

postMessage 是一种允许来自不同源的脚本采用异步方式进行有限通信的Web API。这一功能对于实现跨域消息传递至关重要,尤其是在涉及iframe、窗口以及Web Worker之间的通信场景。

概念:postMessage 方法允许一个窗口(或iframe)向另一个窗口(或iframe)发送消息,即使这两个窗口(或iframe)来源于不同的源(协议+域名+端口)。这对于实现跨域通信是非常有用的技术,因为它不受到同源策略的限制。

用法:postMessage 方法接收两个参数:

  • data:要发送的数据。根据HTML5规范,它可以是任何基本类型或可复制的对象,但在某些较旧的浏览器中,可能只支持字符串。因此,最佳实践是使用JSON.stringify()将对象转换为字符串。
  • origin:指定哪些源的窗口应该接收消息。可以设置为特定的源(如 ‘http://example.com’),或者使用通配符 *
    来允许任何源接收消息(但这存在安全风险,应谨慎使用)。若要限定与当前窗口同源,则可设置为 /

应用场景

  • 页面与其打开的新窗口间的数据传递
  • 多个窗口间的消息传递
  • 主页面与嵌入的iframe间的消息传递

示例
sender.html (位于 domain1.com/sender.html):

<iframe id="iframe" src="http://www.domain2.com/receiver.html" style="display:none;"></iframe>
<script>var iframe = document.getElementById('iframe');iframe.onload = function() {var message = {content: 'Hello from sender!'};iframe.contentWindow.postMessage(JSON.stringify(message), 'http://www.domain2.com');window.addEventListener('message', function(e) {if (e.origin === 'http://www.domain2.com') {alert('Response from receiver: ' + e.data);}}, false);};
</script>

receiver.html (位于 domain2.com/receiver.html):

<script>window.addEventListener('message', function(e) {if (e.origin === 'http://www.domain1.com') {alert('Message received from sender: ' + e.data);var response = {content: 'Hello back to sender!',original: JSON.parse(e.data)};e.source.postMessage(JSON.stringify(response), e.origin);}}, false);
</script>

注意事项

  • 在使用postMessage时,确保正确验证消息来源(即检查event.origin属性),以防止跨站脚本攻击(XSS)。
  • 消息接收方通过监听message事件来接收消息,其中event.data包含发送的数据,而event.origin则标识发送消息的源。

使用e.source.postMessage()而不是window.parent.postMessage()可以更灵活地处理消息的回传,特别是在多个窗口或iframe结构中。

4.Nginx代理跨域

使用Nginx作为代理服务器解决跨域问题,主要利用其强大的反向代理能力和对HTTP头部的灵活控制能力,实现跨源资源共享(CORS)。以下是两种常见的应用场景及其解决方案:

  1. Nginx配置解决iconfont跨域问题
    当静态资源服务器需要向不同源的客户端提供iconfont字体文件(如.eot、.otf、.ttf、.woff、.svg格式)时,虽然大部分静态资源不受同源策略限制,但这些字体文件可能因浏览器的安全策略遇到跨域问题。通过在Nginx配置中添加适当的Access-Control-Allow-Origin头部,可以允许所有源访问这些字体文件,从而解决跨域问题。
location / {add_header Access-Control-Allow-Origin *;
}

这段配置表示对所有请求到该Nginx服务器的资源,响应头中都会包含Access-Control-Allow-Origin: *,允许任何源的请求访问。

  1. Nginx反向代理解决接口跨域问题
    对于前后端分离的应用,尤其是前端请求不同源后端接口的情况,可以通过Nginx设置反向代理来规避浏览器的同源策略限制。
    实现思路是设置一个与前端同源(域名相同,端口可以不同)的Nginx代理服务器,该服务器接收前端的请求,然后作为“中转站”去访问实际后端服务(domain2),并将后端响应转发回前端。这样,从浏览器的角度看,请求和响应都在同一个源下,避免了跨域问题。
server {listen       81; # 代理服务器监听的端口server_name  www.domain1.com; # 与前端同源的域名location / {proxy_pass   http://www.domain2.com:8080;  # 反向代理至实际后端接口地址proxy_cookie_domain www.domain2.com www.domain1.com; # 修改响应中Set-Cookie的Domain属性,使前端能正确保存cookie# 当前端请求需要带cookie且涉及到跨域时,需要设置如下头部add_header Access-Control-Allow-Origin http://www.domain1.com; # 允许特定源的跨域请求add_header Access-Control-Allow-Credentials true; # 允许携带凭证(如cookies)# 如果前端请求不涉及cookie,可以简化为# add_header Access-Control-Allow-Origin *;}
}

这段配置不仅实现了接口的跨域访问,还通过proxy_cookie_domain指令修改了后端返回的Cookie中Domain属性,确保了前端能够正确存储和使用这些Cookie,这对于需要认证或状态保持的场景尤为重要。

请注意,当设置Access-Control-Allow-Credentials为true时,Access-Control-Allow-Origin不能设置为*,而应指定确切的源地址,以确保安全性。

5.Node.js中间件代理跨域

在Node.js中使用中间件实现跨域代理,是一种常见的处理前后端分离项目中跨域请求问题的方法。此方法通过在Node.js服务器上部署一个代理层,将前端的跨域请求转发到目标后端服务器,有效绕过了浏览器的同源策略限制。下面分别介绍非Vue框架和Vue框架下的跨域代理实现方式。

  1. 非Vue框架下的跨域代理

使用Express框架配合http-proxy-middleware中间件可以快速搭建一个代理服务器,用于转发前端请求到后端API服务器,并处理跨域问题。

前端请求示例:

var xhr = new XMLHttpRequest();
xhr.withCredentials = true; // 允许携带cookie
xhr.open('GET', 'http://www.domain1.com:3000/login?user=admin', true);
xhr.send();

Node.js服务器配置:

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();app.use('/', createProxyMiddleware({target: 'http://www.domain2.com:8080', // 目标API服务器地址changeOrigin: true, // 改变请求源头,模拟从代理服务器发起请求onProxyRes: function(proxyRes, req, res) {res.header('Access-Control-Allow-Origin', 'http://www.domain1.com'); // 设置允许的源res.header('Access-Control-Allow-Credentials', 'true'); // 允许携带凭证},cookieDomainRewrite: 'www.domain1.com', // 修改响应中Cookie的Domain
}));app.listen(3000, () => {console.log('Proxy server is running on port 3000');
});
  1. Vue框架下的跨域代理

在Vue项目开发过程中,通常会使用Webpack作为打包工具,webpack-dev-server提供了内置的代理功能,可以直接在webpack.config.js中配置接口代理,简化跨域处理流程。

webpack.config.js配置示例:

module.exports = {// ...其他配置devServer: {historyApiFallback: true,proxy: {'/login': { // 匹配的路径target: 'http://www.domain2.com:8080', // 目标API服务器地址changeOrigin: true, // 改变请求源头secure: false, // 如果是HTTPS接口,需要设置为falsecookieDomainRewrite: 'www.domain1.com', // 修改响应中Cookie的Domain}},noInfo: true // 减少输出信息}
};

在Vue项目的开发环境下,通过上述配置,webpack-dev-server会自动拦截前端向/login路径的请求,并将其代理到指定的后端API服务器,同时处理好跨域问题,使得开发者可以无缝对接后端接口进行开发调试,而无需关心跨域问题。

6.document.domain + iframe

在Web开发中,当遇到主域相同但子域不同的跨域问题时,可以通过修改document.domain属性的方法结合<iframe>标签来实现跨域通信。这种方法适用于那些拥有共同顶级域名的页面间的通信需求。具体实施步骤如下:

实现原理:
设置document.domain: 两个页面——即父页面和子页面(通过<iframe>嵌入)——都需要通过JavaScript设置它们的document.domain属性为相同的高级别主域。这样做是为了让浏览器认为这两个页面处于同一个域下,从而绕过同源策略的限制。

应用场景:
限制条件: 此方案仅适用于主域名相同,但子域名不同的场景。例如,a.example.com和b.example.com可以使用此方法通信,但example.com与anotherexample.com则不适用。

示例代码
父窗口页面 (domain.com/a.html):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Parent Window</title>
</head>
<body><iframe id="iframe" src="http://child.domain.com/b.html"></iframe><script>document.domain = 'domain.com'; // 设置document.domain为共同的基础主域var user = 'admin'; // 父窗口定义的变量</script>
</body>
</html>

子窗口页面 (child.domain.com/b.html):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Child Window</title>
</head>
<body><script>document.domain = 'domain.com'; // 子窗口同样设置document.domain为共同的基础主域// 从父窗口获取变量console.log('获取父窗口数据: ' + window.parent.user);</script>
</body>
</html>

注意事项

  • 安全考量: 虽然此方法可以解决特定条件下的跨域问题,但在实施前需仔细考虑安全因素,确保不会无意间暴露敏感信息或引入安全漏洞。
  • 适用范围: 仅限于同主域名下的子域名相互通讯,对于完全不同域名间的跨域问题无效。
  • 现代替代方案:随着CORS(跨源资源共享)和WebSocket等技术的发展,对于跨域数据交换的需求,更多地倾向于使用这些现代标准,因为它们提供了更为灵活和安全的跨域通信机制。

7.Location.hash + iframe

在早期的Web开发中,为了解决跨域通信问题,开发者常采用location.hash + iframe的技巧,这是一种较为原始且有限制的跨域通讯方法。这种方法通过URL的hash部分传递信息,利用不同页面间的iframe元素和同源策略的特性,实现在一定条件下的跨域数据交换。以下是该方法的具体实施步骤和示例代码的描述:

实现原理

  • 借助iframe和hash值传递信息:不同源的页面间不能直接进行JavaScript通信,但可以通过iframe加载另一个页面,并利用URL的hash部分传递数据。因为改变iframe的src的hash部分不会引起页面刷新,且hash变化会触发onhashchange事件,这为跨域数据传输提供了可能。
  • 中间人页面:在两个不同源的页面A和B之间,通常需要一个同源于A的中间页面C来完成闭环通信。C页面可以访问A页面的JavaScript上下文,从而实现数据的最终传递。

具体实现步骤:
a.html (位于 domain1.com)

  • 创建一个隐藏的iframe,其src指向B域的b.html。
  • 通过setTimeout设置延迟,改变iframe的src,附加hash值(如#user=admin),以此向B域的页面传递信息。
  • 定义一个全局函数onCallback,供同源的C页面调用来回传数据。

b.html (位于 domain2.com)

  • 同样包含一个隐藏的iframe,其src指向A域的c.html。
  • 监听自身的onhashchange事件,一旦hash值发生变化(即接收到A域传来的信息),立即将此hash值附加到C页面的iframe src中,间接传递给C页面。

c.html (位于 domain1.com)

  • 作为同源于A页面的中间人,监听自身的onhashchange事件。
  • 解析接收到的hash值,通过window.parent.parent访问到A页面的上下文,并调用预先定义好的onCallback函数,将处理后的信息回传给A页面。

示例代码摘要:
a.html:

<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>var iframe = document.getElementById('iframe');setTimeout(function() {iframe.src += '#user=admin';}, 1000);function onCallback(res) {alert('Data from c.html ---> ' + res);}
</script>

b.html:

<iframe id="iframe" src="http://www.domain1.com/c.html" style="display:none;"></iframe>
<script>var iframe = document.getElementById('iframe');window.onhashchange = function () {iframe.src += location.hash;};
</script>

c.html:

<script>window.onhashchange = function () {var res = 'hello: ' + location.hash.replace('#user=', '');window.parent.parent.onCallback(res);};
</script>

注意事项

  • 此方法受限于同源策略,且通信效率较低,用户体验可能受影响。
  • 现代Web开发中,更推荐使用CORS(跨源资源共享)、WebSockets或Fetch API等技术来处理跨域问题,它们提供更强大、灵活且安全的跨域通信能力 。

8.window.name + iframe跨域

利用 window.name 和 iframe 实现跨域通信是一种巧妙的技术手段,尤其适用于那些受到同源策略限制的场景。这种方法的核心在于利用了 window.name 属性的两个特性:一是其值在页面跳转时可以保持不变,即使跳转到完全不同域名的页面;二是它可以存储异常大量的数据(理论上可达2MB),这为跨域数据交换提供了便利。
a.html (domain1.com/a.html)

var proxy = function(url, callback) {var state = 0;var iframe = document.createElement('iframe');iframe.src = url; // 设置iframe的src为跨域页面iframe.onload = function() {if (state === 1) {// 第二次加载(同域proxy页面)完成,读取并处理数据callback(iframe.contentWindow.name);destroyFrame();} else if (state === 0) {// 第一次加载(跨域页面)成功,转向同域代理页面iframe.contentWindow.location = 'http://www.domain1.com/proxy.html';state = 1;}};document.body.appendChild(iframe);function destroyFrame() {iframe.contentWindow.document.write('');iframe.contentWindow.close();document.body.removeChild(iframe);}// 请求跨域b页面的数据proxy('http://www.domain2.com/b.html', function(data) {alert(data); // 数据展示或进一步处理});
};

proxy.html (domain1.com/proxy.html)
此页面仅作为中转站,确保跨域数据能通过同源策略传递回主页面。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Proxy Page</title>
</head>
<body>
<!-- 此页面无需任何额外代码,为了作为同源策略下的数据中转 -->
<!-- 跨域数据在window.name中已准备好,将被父页面通过iframe访问 -->
</body>
</html>

b.html (domain2.com/b.html)

<script>window.name = 'This is domain2 data!'; // 跨域数据存储于window.name
</script>
  1. 工作原理 起始:a.html 使用 proxy 函数创建 iframe,指向跨域的 b.html。
  2. 数据载入:b.html 将数据写入 window.name。
  3. 回程代理:首次加载完毕后,iframe 的 src 被重定向到同域的 proxy.html,此时 window.name
    的数据依然保留。
  4. 数据提取与处理:proxy.html 加载时(第二次 onload 触发),因同源关系,可以从 iframe 提取
    window.name 中的数据并通过回调函数返回给 a.html。
  5. 资源清理:数据处理完毕后,iframe 被销毁,确保安全及资源管理。

安全考量
尽管此技术可规避浏览器的跨域访问限制,但实施时务必重视数据的安全性和隐私保护,确保跨域通信活动遵循网络安全最佳实践和法规要求。

9.WebSocket协议跨域

WebSocket协议是一种在HTML5中引入的通信协议,它允许浏览器和服务器之间建立全双工、低延迟的通信渠道,特别适用于实现实时交互和服务器推送技术。相较于传统的HTTP请求,WebSocket能够维持长时间的连接状态,且双向通信无需重复握手,提高了效率和实时性。此协议还支持跨域通信,打破了同源策略的限制,使得不同源的客户端与服务器能直接进行数据交换。

为了简化WebSocket的使用,通常会采用如Socket.io这样的库,它不仅对WebSocket API进行了高级封装,提供了更易于使用的接口,还对不兼容WebSocket的旧版浏览器提供了向下兼容的支持。

客户端(前端)代码示例
HTML部分包含一个文本输入框供用户输入数据,JavaScript部分则通过Socket.io与服务器建立WebSocket连接。

<!-- HTML部分 -->
<div>用户输入:<input type="text"></div><!-- 引入Socket.io库 -->
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script><!-- JavaScript部分 -->
<script>// 创建Socket.io实例并连接到服务器var socket = io('http://www.domain2.com:8080');// 监听连接成功的事件socket.on('connect', function() {// 监听来自服务器的消息socket.on('message', function(msg) {console.log('从服务器收到的数据: ---> ' + msg);});// 监听服务器断开连接的事件socket.on('disconnect', function() {console.log('服务器连接已关闭.');});});// 当用户在输入框中失去焦点时,发送输入值到服务器document.getElementsByTagName('input')[0].onblur = function() {socket.send(this.value);};
</script>

服务器端(Node.js)代码示例
使用Node.js和Socket.io创建一个简单的WebSocket服务器,监听8080端口,并处理客户端的连接与消息。

// 引入必要的模块
var http = require('http');
var socket = require('socket.io');// 创建HTTP服务器
var server = http.createServer(function(req, res) {res.writeHead(200, {'Content-type': 'text/html'});res.end();
});// 服务器监听8080端口
server.listen(8080);
console.log('服务器正在8080端口运行...');// 使用Socket.io监听服务器上的WebSocket连接
socket.listen(server).on('connection', function(client) {// 接收到客户端消息时的处理client.on('message', function(msg) {// 向客户端回复消息client.send('你好:' + msg);console.log('从客户端收到的数据: ---> ' + msg);});// 处理客户端断开连接client.on('disconnect', function() {console.log('客户端连接已关闭.');});
});

以上示例展示了如何利用Socket.io在前端和后端之间快速搭建WebSocket通信,包括如何处理连接、消息收发和断开连接等核心功能。

5.正向代理与反向代理的区别

特性正向代理反向代理
目的允许客户端通过代理访问受限资源提高服务端性能,负载均衡,隐藏后端服务器
设置方客户端服务器端
代理对象客户端(隐藏客户端)服务器(隐藏服务器)
透明性需客户端配置,不透明对客户端透明,无需客户端配置
配置需求修改客户端网络设置(如浏览器)修改DNS指向代理服务器,客户端无感知
应用场景访问控制、隐私保护、地域限制突破负载均衡、SSL终止、安全防护、CDN
示例个人使用代理服务器浏览国外网站Nginx作为网站前端,分配请求到后端服务器

正向代理(Forward Proxy)

  • 目的:帮助客户端访问受限资源。当客户端因网络策略、地理位置限制等原因无法直接访问目标服务器时,正向代理作为中介,接收客户端的请求,然后转发给目标服务器,并将服务器响应传回客户端。
  • 设置方:由客户端负责配置代理服务器信息,可能涉及修改浏览器或其他客户端应用的网络设置。
  • 作用:隐藏客户端的真实身份,对外展现的是代理服务器的IP地址。
  • 配置需求:需要在客户端进行代理服务器的配置。

反向代理(Reverse Proxy)

  • 目的:优化服务端架构,提高服务的可用性和安全性。反向代理服务器接收来自客户端的请求,根据预定义的规则决定将请求分配给后端的哪一个服务器处理,随后将服务器响应返回给客户端。
  • 设置方:由服务器端部署和管理,对客户端透明。
  • 作用:隐藏后端服务器的具体信息,提供统一的入口,实现负载均衡、SSL终止、缓存及安全防护等功能。
  • DNS配置:通常通过修改DNS记录,使域名解析到反向代理服务器的IP地址,客户端无需知晓后端服务器的细节。

正向代理流程:👇正向代理流程描述了客户端通过配置的代理服务器(Proxy)向目标服务器(Target_Server)请求数据的过程。

发出请求
转发请求
响应数据
返回数据给客户端
Client
Proxy
Target_Server

反向代理流程:👇反向代理流程则展示了客户端请求通过反向代理服务器(Reverse_Proxy),该代理服务器根据策略选择合适的真实服务器(Real_Server)处理请求,并将响应返回给客户端的场景。

发出请求
智能路由到
处理并响应
返回响应给客户端
Client
Reverse_Proxy
Real_Server

核心差异

尽管正向代理和反向代理在结构上都表现为 client-proxy-server,但关键区别在于代理服务器的部署位置和代理服务的目标:

  • 部署位置:正向代理靠近客户端,由客户端配置使用;反向代理则部署在服务器端,对客户端透明。
  • 目标:正向代理旨在隐藏客户端,帮助客户端访问资源;反向代理则是隐藏服务器端详情,提供额外的安全性、性能优化和负载均衡能力。

综上所述,正向代理和反向代理的主要区别在于代理服务的侧重点和部署策略,分别服务于客户端的需求隐藏和服务器端的架构优化及安全增强。

6.Nginx

Nginx概念及工作原理

Nginx 是一款轻量级的 Web 服务器软件,专为高效率和低资源消耗而设计。除了基本的网页服务功能,Nginx 还能作为反向代理服务器、负载均衡器以及实现HTTP缓存策略,广泛应用于构建高性能的现代网络架构。

核心特性

  • 异步事件驱动模型:区别于传统服务器如Apache采用的进程或线程模型,Nginx运用了事件驱动的方式处理请求,这种机制使它能够以更少的资源处理更多的并发连接,显著提升了处理能力与响应速度。

架构层次

Master Process(主进程)

  • 管理与控制:Nginx架构的顶级元素是master process,负责加载配置、监控状态以及维护工作进程的生命周期,但不直接参与请求处理。

Worker Processes(工作进程)

  • 并发处理核心:由主进程创建的worker processes承担了实际的请求处理工作。得益于事件驱动设计,每个worker进程能够同时处理大量HTTP请求,无需为每个请求分配单独的线程或进程,这是Nginx在性能上超越诸如Apache(后者基于每个连接/请求分配独立进程的模型)的关键所在。

工作流程

  1. 请求接收:客户端发起HTTP请求至Nginx服务器。
  2. 请求分发:Nginx可根据配置执行反向代理或负载均衡功能,将请求智能路由到后端服务器。
  3. 高效处理:利用epoll(Linux环境下)等I/O多路复用技术,工作进程异步非阻塞地监听和响应事件,即使面对文件I/O或后端响应等待,也能继续处理其他请求。
  4. 响应与缓存:处理完成后,将响应数据返回客户端;对于静态资源,Nginx可实施缓存策略加速后续相同请求的响应。

综上所述,Nginx凭借其独特的事件驱动架构和高度优化的工作进程模型,在处理高并发场景时展现出卓越的性能,成为众多大型网站和服务的首选基础架构组件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37802.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【教学类65-04】20240625秘密花园涂色书04(通义万相)(图纸16:9,A4横板1张,一大168张纸168份)

背景需求 【教学类65-01】20240622秘密花园涂色书01&#xff08;通义万相&#xff09;&#xff08;A4横版2张&#xff0c;一大3小 38张纸76份&#xff09;-CSDN博客文章浏览阅读118次。【教学类65-01】20240622秘密花园涂色书01&#xff08;通义万相&#xff09;&#xff08;A…

老年人能力评估系统:在居家养老中的作用

随着人口老龄化趋势的加剧&#xff0c;居家养老成为了许多老年人的首选。为了满足居家养老中老年人能力评估的需求&#xff0c;提高评估质量和效果&#xff0c;老年人能力评估系统应运而生。本文将为您介绍老年人能力评估系统在居家养老中的作用&#xff0c;让您了解这个在居家…

Ubuntu 截图shutter,图像编辑 gimp,录屏kazam

1.截图&#xff1a; Shutter 安装shutter命令&#xff1a; sudo add-apt-repository ppa:shutter/ppasudo apt-get updatesudo apt-get install shutter 2.图片编辑&#xff1a;Gimp, Kolourpaint, Pinta gimp全名为&#xff1a;GNU Image Manipulation Program&#xff0c…

操作系统-文件的物理结构(文件分配方式)

文章目录 总览文件块和磁盘块连续分配顺序访问直接访问&#xff08;随机访问&#xff09;为什么连续分配同时支持这两种访问模式&#xff1f; 链接分配隐式链接显示链接小结索引分配链接方案多层索引混合索引小结 总结 总览 文件数据存放在外存中 文件块和磁盘块 文件内通过逻…

万字长文详解数据结构:树 | 第6章 | Java版大话数据结构 | 二叉树 | 哈夫曼树 | 二叉树遍历 | 构造二叉树 | LeetCode练习

&#x1f4cc;本篇分享的大话数据结构中&#x1f384;树&#x1f384;这一章的知识点&#xff0c;在此基础上&#xff0c;增加了练习题帮助大家理解一些重要的概念✅&#xff1b;同时&#xff0c;由于原文使用的C语言代码&#xff0c;不利于学习Java语言的同学实践&#xff0c;…

Linux中使用网络文件系统NFS挂载远程目录,对远程文件的本地化操作

目录 一、NFS及其在linux系统中的挂载 1、NFS概述 2、NFS挂载及其作用 &#xff08;1&#xff09;资源共享 &#xff08;2&#xff09;简化数据管理 &#xff08;3&#xff09;提高数据可用性 &#xff08;4&#xff09;灵活性 &#xff08;5&#xff09;访问控制 &am…

Elasticsearch 避免常见查询错误和陷阱

Elasticsearch 作为一款强大的搜索引擎和分析工具&#xff0c;已经被广泛应用于各种场景中。然而&#xff0c;在使用 Elasticsearch 进行查询时&#xff0c;如果不注意一些常见的错误和陷阱&#xff0c;可能会导致查询效率低下、结果不准确甚至系统性能下降。本文旨在总结一些常…

web刷题记录(7)

[HDCTF 2023]SearchMaster 打开环境&#xff0c;首先的提示信息就是告诉我们&#xff0c;可以用post传参的方式来传入参数data 首先考虑的还是rce&#xff0c;但是这里发现&#xff0c;不管输入那种命令&#xff0c;它都会直接显示在中间的那一小行里面&#xff0c;而实际的命令…

工业自动化控制中心

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace 工业自动化控制中心 {public partial class Form1 : Form{public Form1(){InitializeComponent();}pri…

数据结构与算法笔记:高级篇 - 搜索:如何用 A* 搜索算法实现游戏中的寻路功能?

概述 魔兽世界、仙剑奇侠传这类 MMRPG 游戏&#xff0c;不知道你玩过没有&#xff1f;在这些游戏中&#xff0c;有一个非常重要的功能&#xff0c;那就是任务角色自动寻路。当任务处于游戏地图中的某个位置时&#xff0c;我们用鼠标点击另外一个相对较远的位置&#xff0c;任务…

无线WiFi毫米波雷达传感器成品,智能照明人体感应开关,飞睿智能点亮智慧生活

在智能科技飞速发展的今天&#xff0c;我们的生活正被各种智能设备所包围&#xff0c;其中智能照明作为智能家居的重要组成部分&#xff0c;正逐渐改变着我们的生活方式。而在这背后&#xff0c;有一个默默工作的“小助手”——飞睿智能毫米波雷达传感器&#xff0c;它就像智能…

面试官:10W QPS高并发下,如何防止重复下单?

核心问题 10W QPS&#xff1a;每秒10万次请求&#xff0c;高并发场景。重复下单&#xff1a;用户因网络问题、系统重试、误操作等原因提交多次相同订单。 电商订单支付核心流程 用户下单&#xff1a;选择商品&#xff0c;提交订单。订单确认&#xff1a;系统生成订单号&…

考后热门三件套 国漫年番加点料

学生时代&#xff0c;最开心的莫过于寒暑假&#xff0c;而比寒暑假更开心的必须是升学考后的假期&#xff01;很多同学的考后三件套&#xff1a;聚餐、旅游和学车&#xff01;同样有许多同学开启了补番计划&#xff0c;今天就给大家推荐4部暑期必看的年番&#xff0c;各种类型兼…

PICO 4S泄露信息更新,配备骁龙XR2 Gen 2,单眼分辨率2160×2160

根据最新的泄露信息汇总&#xff0c;PICO 4S确实有望成为一款高性能的VR头显&#xff0c;其核心规格和特性包括&#xff1a; 处理器与内存&#xff1a;搭载了高通骁龙XR2 Gen 2芯片组&#xff0c;这是针对VR/AR设备优化的高端处理器&#xff0c;能提供更强大的计算能力和效率。…

mwwz库添加对多模板匹配的支持:find_shape_models

多模板匹配的实现只需要对单模板匹配做一些扩展&#xff0c;传入的模板由不同的id表示&#xff0c;在金字塔顶层完成模板的分类&#xff0c;在剩下的金字塔完成对每一类模板的匹配&#xff0c;匹配结果由id标识。测试程序已集成该方法&#xff0c;清除模板后所创建的模板被看作…

Vue 鼠标滑入元素改变其背景颜色,且鼠标划入另一块区域,背景颜色保持不变

如上图所示&#xff1a;鼠标划入"条件区域",对应ul元素改变背景颜色&#xff0c;且划入内容区域时&#xff0c;ul元素的背景颜色保持不变。只有当鼠标划出"内容区域"&#xff0c;或者切换到"条件区域"的其他ul元素上时&#xff0c;背景颜色才恢复…

二叉树的层序遍历/后序遍历(leetcode104二叉树的最大深度、111二叉树的最小深度)(华为OD悄悄话、数组二叉树)

104二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 本题可以使用前序&#xff08;中左右&#xff09;&#xff0c;也可以使用后序遍历&#xff08;左右中&#xff09;&#xff0c;…

基于SpringBoot学生信息管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…

qt QTreeWidget文件管理器拖入应用,从应用拖入文件管理器拷贝

我用QT实现了一个文件管理的软件&#xff0c;能够实现从桌面或其他路径拖拽文件到软件&#xff0c;软件获取拖拽文件的路径。但是当我想实现反向操作时遇到了问题。在网上搜索和阅读文档一天多都未能解决该问题。 下面给出我的实现&#xff1a; Qt开发中经常会用QTreeWidget去…

昇思MindSpore学习笔记5--数据变换Transforms

摘要&#xff1a; 昇思MindSpore的数据变换&#xff0c;包括通用变换Common Transforms、图像变换Vision Transforms、标准化Normalize、文本变换Text Transforms、匿名函数变换Lambda Transforms。 一、数据变换Transforms概念 原始数据需预处理后才能送入神经网络进行训练…