【反向代理】跨域解决方式之一——反向代理

笔者在前几天遇到一个跨域问题,请求一个地图瓦片服务,但是地图瓦片服务地址由另一个地图服务商提供的,按照传统的后端解决跨域的手段,主要有两种:

(1)后端设置CORS(这个需要第三方CORS的jar包)
(2)对后端设置跨域访问(即在get或者post等方法中设置 response.setHeader(“Access-Control-Allow-Origin”, “*”);)

具体可以参考:

解决跨域的方法
CORS详解

那么,什么是跨域呢?

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
所谓同源是指,域名,协议,端口相同。浏览器执行javascript脚本时,会检查这个脚本属于那个页面,如果不是同源页面,就不会被执行。
同源策略的目的,是防止黑客做一些做奸犯科的勾当。比如说,如果一个银行的一个应用允许用户上传网页,如果没有同源策略,黑客可以编写一个登陆表单提交到自己的服务器上,得到一个看上去相当高大上的页面。黑客把这个页面通过邮件等发给用户,用户误认为这是某银行的主网页进行登陆,就会泄露自己的用户数据。而因为浏览器的同源策略,黑客无法收到表单数据。

因为笔者遇到的这种情况比较特殊一点,如果是自己写的服务,那么自然可以加上跨域请求的设置,但是如果是请求别的服务商的服务,那么跨域要么和服务商沟通,让他们设置允许来自某域名的跨域访问。要么就需要像本文一样,自己设置一个反向代理的服务器,或者自己编写一个代理服务。

代理服务其实就是把前端的跨域请求,通过代理进行一次转发,代理执行真正的访问另一域名下的服务(因为后端调用另一域名下的服务是不存在跨域问题的),将访问后的结果返回给前端。

本文针对代理,提供两种解决方案,一种是后端自己编码,一种是使用Nginx代理。

(1)编码
笔者采用vertx自己编写代理服务(需要利用vertx的core包)
示例:

package util;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientOptions;
import io.vertx.core.http.HttpClientRequest;

/**
 * 代理
 * @author KingWang
 *
 */
public class Proxy extends AbstractVerticle {

  @Override
  public void start() throws Exception {
    HttpClient client = vertx.createHttpClient(new HttpClientOptions());
    vertx.createHttpServer().requestHandler(req -> {
      System.out.println("Proxying request: " + req.uri());
      HttpClientRequest c_req = client.request(req.method(), 25033, "10.73.199.229", req.uri(), c_res -> {
        System.out.println("Proxying response!");
//        System.out.println("Proxying response:" + c_res.statusCode());
        req.response().setChunked(true);
        req.response().setStatusCode(c_res.statusCode());
        req.response().headers().setAll(c_res.headers());
        c_res.handler(data -> {
          System.out.println("Proxying response body");
//          System.out.println("Proxying response body: " + data.toString("ISO-8859-1"));
          req.response().write(data);
        });
        c_res.endHandler((v) -> req.response().end());
      });
      c_req.setChunked(true);
      c_req.headers().setAll(req.headers());
      req.handler(data -> {
        System.out.println("Proxying request body ");
//        System.out.println("Proxying request body " + data.toString("ISO-8859-1"));
        c_req.write(data);
      });
      req.endHandler((v) -> c_req.end());
    }).listen(1001);
  }
}

(2)使用Nginx代理

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

使用Nginx代理只需要几行配置代码就可以了。

首先下载Nginx并安装(不能安装在中文目录下)

然后在conf目录下的nginx.conf配置相应的反向代理路径

示例(本示例配置的是可以配置多个代理路径,也就是多个server标签):


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       8081;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值