八、浏览器同源策略

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

文章目录

  • 浏览器同源策略
    • 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接口,需要设置为false
                cookieDomainRewrite: '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.mfbz.cn/a/757890.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Webpack: 核心配置结构

概述 Webpack 是一种 「配置」 驱动的构建工具&#xff0c;所以站在应用的角度&#xff0c;必须深入学习 Webpack 的各项配置规则&#xff0c;才能灵活应对各种构建需求。本文将作为小册应用系列的一个总结&#xff0c;汇总与应用配置相关的各项知识点&#xff0c;包括&#x…

酒店客房管理系统(Java+MySQL)

技术栈 Java: 作为主要编程语言。Swing GUI: 用于开发图形用户界面。MySQL: 作为数据库管理系统。JDBC: 用于连接和操作MySQL数据库。 功能要点 管理登录认证 系统提供管理员登录认证功能。通过用户名和密码验证身份&#xff0c;确保只有授权的用户可以访问和管理酒店客房信…

数据结构复习指南

数据结构复习指南 本文中列举了数据结构期末考试可能存在的考点 绪论 数据的基本单位 数据元素是数据的基本单位 数据项 数据项是组成数据的、有独立含义的、不可分割的最小单位。 数据对象 数据对象是性质相同的数据元素的集合&#xff0c;是数据的一个子集。 数据结…

KBL410-ASEMI智能AI专用整流桥KBL410

编辑&#xff1a;ll KBL410-ASEMI智能AI专用整流桥KBL410 型号&#xff1a;KBL410 品牌&#xff1a;ASEMI 封装&#xff1a;KBL-4 正向电流&#xff08;Id&#xff09;&#xff1a;4A 反向耐压&#xff08;VRRM&#xff09;&#xff1a;1000V 正向浪涌电流&#xff1a;2…

系统运维面试总结(系统权限)

系统运维面试总结&#xff08;系统权限&#xff09; 一、权限优化简述Linux权限划分原则二、备份策略三、Raid四、资源查看五、Linux启动流程 一、权限优化简述Linux权限划分原则 ckhunter也是一款常用的Linux杀毒软件 不可修改但可删除 二、备份策略 供参考较为全面的备份方案…

【操作系统】进程管理——进程的概念、组成和特征(个人笔记)

学习日期&#xff1a;2024.6.29 内容摘要&#xff1a;进程的基本概念和特征、状态和转换 进程的概念 程序与进程 程序&#xff1a;是静态的&#xff0c;是存放在磁盘里的可执行文件&#xff0c;就是一系列的指令集合 进程&#xff08;Process&#xff09;&#xff1a;是动态…

基于STM32的智能家用电力管理系统

目录 引言环境准备智能家用电力管理系统基础代码实现&#xff1a;实现智能家用电力管理系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;电力管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家用电力管理系统通…

6.优化算法之模拟

1.替换所有的问号 . - 力扣&#xff08;LeetCode&#xff09; class Solution {public String modifyString(String s) {char[] sss.toCharArray();int nss.length;for(int i0;i<n;i){if(ss[i]?){for(char cha;ch<z;ch){if((i0||ss[i-1]!ch)&&(in-1||ss[i1]!c…

湖南(市场调研)源点咨询 市场研究中定性调研的优势与局限性

定性调研指的是调研的结果不经量化或数量分析。 它通常用于分析态度、感觉和动机。定性调研特别是焦点小组访谈法还在继续普及&#xff0c;原因有以下三个&#xff1a; 第一&#xff0c;定性调研通常比定量调研成本低&#xff1b; 第二&#xff0c;定性调研在了解消费者内心…

滑动窗口2

1. 水果成篮&#xff08;904&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 根据题目意思&#xff0c;friuts表示第i棵树上的水果种类&#xff0c;然后我们有两个篮子去在这些树上去采水果&#xff0c;但是有限制就是一个篮子里就只能装一种水果&#xff0c;也就是…

【简单讲解下OneFlow深度学习框架】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

SM2258XT量产工具,SM2258XT开卡三星SSV4颗粒成功分享,SM2259XT量产参考教程,威刚ADATA SP580开卡记录

前两天拆了笔记本上的威刚ADATA SP580 240GB&#xff0c;准备做移动硬盘用&#xff0c;装入移动硬盘盒之后接入电脑&#xff0c;发现系统可认盘&#xff0c;SMART显示正常&#xff0c;Windows的磁盘管理能显示正确容量&#xff0c;但处于未初始化状态&#xff0c;且始终无法初始…

病理性不对称引导的渐进学习用于急性缺血性脑卒中梗死分割| 文献速递-先进深度学习疾病诊断

Title 题目 Pathological Asymmetry-Guided Progressive Learning for Acute Ischemic Stroke Infarct Segmentation 病理性不对称引导的渐进学习用于急性缺血性脑卒中梗死分割 01 文献速递介绍 中风已经成为第二大致命疾病&#xff0c;大约70%的中风是缺血性的。众所周知…

AI in Law 法律领域AI应用-基于DeepNLP AI App Store 评论评测和排名

来源: quora 社区: https://deepnlpaistore.quora.com/ github: https://github.com/rockingdingo/deepnlp/blob/master/store/law.md 法律领域哪些AI服务应用更能满足用户的需求&#xff0c;排名最高? 参考deepnlp.org网站根据用户真实评论打分和show case分享&#xff0c;分…

java基于ssm+jsp 二手手机回收平台系统

1前台首页功能模块 二手手机回收平台系统&#xff0c;在系统首页可以查看首页、手机商城、新闻资讯、我的、跳转到后台、购物车等内容&#xff0c;如图1所示。 图1前台首页功能界面图 用户注册&#xff0c;在用户注册页面可以填写账号、密码、姓名、手机、邮箱、照片、地址、…

论文工具使用---connected papers

如何使用connected papers 使用方法具体功能其他资源 官网地址&#xff1a;connected papers &#xff1a;一个旨在帮助科研工作者快速搜索文献的全新工具&#xff0c;可以清晰的查看文献的引文信息&#xff0c;了解文献的引用和被引用关联。 使用方法 输入论文标题后&#xf…

如何配置Redis + Rdis在IDEA中的使用

文章目录 Step1. 下载zipStep2. 修改环境变量Step3. 启动Redis服务端Step4. 启动Redis客户端Step5. IDEA中链接Redis Step1. 下载zip 下载 Redis-x64-xxx.zip压缩包&#xff0c;解压到 E 盘后&#xff0c;将文件夹重新命名为 redis 下载地址&#xff1a;Redis下载地址 Step2…

Java----面向对象----总复习

面向对象 面向对象的程序设计思想(Object Oriented Programming),简称OOP.是一种设计者思想.关注的焦点是类,参照现实中的事务,将事务的属性特征,行为抽象出来,用类来表示.代码结构:以类为组织单位,每种事务都有自己的属性和行为,功能, 思想:从宏观上 帮助我们把握,整体分析整…

C语言的数据结构:树与二叉树(哈夫曼树篇)

前言 上篇讲完了二叉树&#xff0c;二叉树的查找性能要比树好很多&#xff0c;如平衡二叉树保证左右两边节点层级相差不会大于1&#xff0c;其查找的时间复杂度仅为 l o g 2 n log_2n log2​n&#xff0c;在两边层级相同时&#xff0c;其查找速度接近于二分查找。1w条数据&am…

160相交链表

解法1&#xff1a; public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {// 定义两个指针。// 获得两个链表的长度&#xff0c;将较长的链表先用指针移动到和短链表一样的长度。// 再一个个比较ListNode l1 headA, l2 headB;int …