Thanks to visit codestin.com
Credit goes to github.com

Skip to content

http代理 #10

@andyChenAn

Description

@andyChenAn

http代理

http代理,对于大部分程序员来说应该都是用过的,而作为前端,我一般用它来进行跨域访问。当然http代理的功能有很多,比如拦截,监控,过滤,缓存等这些都可以通过http代理来实现。

什么是http代理?

http代理,对于客户端和服务器来说就是一个中间人的角色,对于连接它的客户端来说,它是服务器,对于它连接的服务器来说,它是客户端,而http代理主要就是来回传送客户端和服务器之间的http报文。

http代理有什么功能?

http代理可以实现的功能比较多,比如:拦截,监控,过滤,web缓存,跨域,反向代理等。这些功能都可以通过代理来实现。

1、拦截功能:

比如我们需要拦截用户登录,如果用户已经登录,那么就直接返回页面,如果用户还没有登录,就重定向到用户登录页面,引导用户登录。或者页面存在权限控制,针对不同权限返回不同页面信息。

2、监控功能:

比如我们需要监控代码异常情况进行上报,那么我们需要监控特定的请求接口,如果有请求,我们就将异常进行上报。

3、过滤功能:

比如我们可以设置有些人可以访问我们的网站,有些人不能访问我们的网站。

4、web缓存功能:

每次请求一个页面时,代理服务器都会检查这个页面是否已经缓存在本地,如果在,就直接返回页面,如果不在,那么再向目标服务器发送请求获取页面,并缓存在代理服务器本地。

5、跨域功能:

我们经常需要跨域访问一些服务器上的数据,这个时候我们可以在同域下创建一个代理服务器,然后由代理服务器去请求不同域名下的服务器上的数据。

6、反向代理功能:

当我们访问一个网址,其实nginx会接收到我们的请求,然后由nginx再转发给其他服务器,其中nginx就实现了反向代理的功能,对于客户端来说,并不知道是由哪一台服务器来返回页面的。

正向代理和反向代理的区别

http代理可以分为正向代理和反向代理,它们之间的区别主要在于代理的对象不一样,正向代理,代理的对象是客户端,主要是为客户端收发请求,而反向代理,代理的是服务端,主要是为服务端收发请求。

简单例子:
const http = require('http');
const url = require('url');

http.createServer(function (req , res) {
    let proxyHeaders = {
        'X-Forwarded-For' : 'localhost',
        "X-Forward-IP" : req.connection.remoteAddress
    };
    let proxyClient = http.request({
        hostname : 'localhost',
        port : 8080,
        headers : proxyHeaders
    });
    req.pipe(proxyClient);
    proxyClient.on('response' , function (proxyResponse) {
        proxyResponse.pipe(res);
    });
}).listen(3000);
console.log('listening port 3000');

http隧道代理

客户端先发送connect请求到隧道代理服务器,告诉隧道代理服务器,建立和服务器的TCP连接,代理服务器成功和后端建立连接后,代理服务器会返回“HTTP/1.1 200 Connection Established”报文,告诉客户端连接已经成功建立,这个时候建立了连接,所以发给代理服务器的TCP报文都会直接转发到目标服务器,从而实现了客户端和服务器的通信。
客户端代码:

var http = require('http');
var https = require('https');
var options = {
    hostname : '127.0.0.1',
    port     : 8080,
    path     : 'www.baidu.com:80',
    method     : 'CONNECT'
};

var req = http.request(options);

req.on('connect', function(res, socket) {
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.baidu.com:80\r\n' +
                 'Connection: Close\r\n' +
                 '\r\n');

    socket.on('data', function(chunk) {
        console.log(chunk.toString());
    });

    socket.on('end', function() {
        console.log('socket end.');
    });
});

req.end();

代理服务器代码:

const http = require('http');
const net = require('net');
const url = require('url');
let proxy = http.createServer();
proxy.on('connect' , function (req , cltSocket , head) {
    let u = url.parse('http://' + req.url);
    let pSock = net.connect(u.port , u.hostname , function () {
        cltSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
        pSock.pipe(cltSocket);
    });
    cltSocket.pipe(pSock);
});
proxy.listen(8080);
console.log('listening port 8080');

https隧道代理:

// https隧道代理服务器
const https = require('https');
const net = require('net');
const url = require('url');
const fs = require('fs');
let options = {
    key : fs.readFileSync('./private.pem'),
    cert : fs.readFileSync('./public.crt')
};
let proxy = https.createServer(options);
proxy.on('connect' , function (req , cltSocket , head) {
    let u = url.parse('http://' + req.url);
    let pSock = net.connect(u.port , u.hostname , function () {
        cltSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
        pSock.pipe(cltSocket);
    });
    cltSocket.pipe(pSock);
});
proxy.listen(8080);
console.log('listening port 8080');
// https,connect请求
var http = require('http');
var https = require('https');
var options = {
    hostname : '127.0.0.1',
    port     : 8080,
    path     : 'www.jobui.com:80',
    method     : 'CONNECT'
};
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var req = https.request(options);
req.on('connect', function(res, socket) {
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.jobui.com:80\r\n' +
                 'Connection: Close\r\n' +
                 '\r\n');

    socket.on('data', function(chunk) {
        console.log(chunk.toString());
    });

    socket.on('end', function() {
        console.log('socket end.');
    });
});

req.end();

Metadata

Metadata

Assignees

No one assigned

    Labels

    httphttp相关知识

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions