Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 685|回复: 0

用nginx的反向代理机制解决前端跨域问题在nginx上部署web静态页面

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-7 15:18:38 | 显示全部楼层 |阅读模式

    用nginx的反向代理机制解决前端跨域问题在nginx上部署web静态页面

     

    1.什么是跨域以及产生原因

      跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。

      跨域情况如下:

     

    url 说明 是否跨域
    http://www.cnblogs.com/a.js
    http://www.a.com/b.js
    不同域名
    http://www.a.com/lab/a.js
    http://www.a.com/script/b.js
    同一域名下不同文件夹
    http://www.a.com:8000/a.js
    http://www.a.com/b.js
    同一域名,不同端口
    http://www.a.com/a.js
    https://www.a.com/b.js
    同一域名,不同协议
    http://www.a.com/a.js
    http://70.32.92.74/b.js
    域名和域名对应ip
    http://www.a.com/a.js
    http://script.a.com/b.js
    主域相同,子域不同 是(cookie不可访问)
    http://www.a.com/a.js
    http://a.com/b.js
    同一域名,不同二级域名(同上)

     

    2.跨域的常见解决方法

    目前来讲没有不依靠服务器端来跨域请求资源的技术

      1.jsonp 需要目标服务器配合一个callback函数。

      2.window.name+iframe 需要目标服务器响应window.name。

      3.window.location.hash+iframe 同样需要目标服务器作处理。

      4.html5的 postMessage+ifrme 这个也是需要目标服务器或者说是目标页面写一个postMessage,主要侧重于前端通讯。

      5.CORS  需要服务器设置header :Access-Control-Allow-Origin。

      6.nginx反向代理 这个方法一般很少有人提及,但是他可以不用目标服务器配合,不过需要你搭建一个中转nginx服务器,用于转发请求。

    3.nginx反向代理解决跨域

      上面已经说到,禁止跨域问题其实是浏览器的一种安全行为,而现在的大多数解决方案都是用标签可以跨域访问的这个漏洞或者是技巧去完成,但都少不了目标服务器做相应的改变,而我最近遇到了一个需求是,目标服务器不能给予我一个header,更不可以改变代码返回个script,所以前5种方案都被我否决掉。最后因为我的网站是我自己的主机,所以我决定搭建一个nginx并把相应代码部署在它的下面,由页面请求本域名的一个地址,转由nginx代理处理后返回结果给页面,而且这一切都是同步的。

     

      关于nginx的一些基本配置和安装请看我的另一篇博客,下面直接讲解如何配置一个反向代理。

     

      首先找到nginx.conf或者nginx.conf.default 或者是default里面的这部份   

              

       其中server代表启动的一个服务,location 是一个定位规则。

    1
    2
    3
    4
    5
    6
    7
    location /{   #所有以/开头的地址,实际上是所有请求
     
    root  html     #去请求../html文件夹里的文件,其中..的路径在nginx里面有定义,安装的时候会有默认路径,详见另一篇博客
     
    index  index.html index.htm  #首页响应地址
     

      

      从上面可以看出location是nginx用来路由的入口,所以我们接下来要在location里面完成我们的反向代理。

      假如我们我们是www.a.com/html/msg.html 想请求www.b.com/api/?method=1&para=2;

      我们的ajax:

    1
    2
    3
    4
    5
    6
    7
    <br>$.ajax({
    type:  "GET" ,
    url:url,
    success:  function (res){..},
    ....
    })

      

      上面的请求必然会遇到跨域问题,这时我们需要修改一下我们的请求url,让请求发在nginx的一个url下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var  proxyurl = 'msg?method=1&para=2'
    //假如实际地址是 www.c.com/proxy/html/api/msg?method=1&para=2; www.c.com是nginx主机地址
      $.ajax({
    type:  "GET" ,
    url:proxyurl,
    success:  function (res){..},
    ....
    })  

      

      

      再在刚才的路径中匹配到这个请求,我们在location下面再添加一个location。

    1
    2
    3
    4
    location ^~/proxy/html/{
    rewrite ^/proxy/html/(.*)$ /$1  break ;
    proxy_pass http: //www.b.com/;
    }

    以下做一个解释

    1.'^~ /proxy/html/ '

      就像上面说的一样是一个匹配规则,用于拦截请求,匹配任何以 /proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。

    2.rewrite ^/proxy/html/(.*)$ /$1 break;

      代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用,例如www.c.com/proxy/html/api/msg?method=1&para=2重写。只对/proxy/html/api/msg重写。

      rewrite后面的参数是一个简单的正则 ^/proxy/html/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。

      break代表匹配一个之后停止匹配。

    3.proxy_pass

      既是把请求代理到其他主机,其中 http://www.b.com/ 写法和 http://www.b.com写法的区别如下:

    不带/

    1
    2
    3
    4
    location /html/
    {
      proxy_pass http: //b.com:8300; 
    }

    带/

    1
    2
    3
    4
    location /html/ 
         proxy_pass http: //b.com:8300/; 
    }

    上面两种配置,区别只在于proxy_pass转发的路径后是否带 “/”。

      针对情况1,如果访问url = http://server/html/test.jsp,则被nginx代理后,请求路径会便问http://proxy_pass/html/test.jsp,将test/ 作为根路径,请求test/路径下的资源。

      针对情况2,如果访问url = http://server/html/test.jsp,则被nginx代理后,请求路径会变为 http://proxy_pass/test.jsp,直接访问server的根资源。

     

    修改配置后重启nginx代理就成功了。

     

    1.mac使用ssh命令登陆远程主机

       因为苹果mac os x自带ssh命令,所以我们只需打开终端输入 

    1
    $ ssh user@remote

      在这之前最好在服务器上上传自己的ssh key,避免每次登陆输入密码

          稍作等待就连接上服务器了

     

     

     

     

    2.mac使用scp命令向远处主机上传文件

            在终端窗口,按下command+n,打开另一个终端窗口,并输入

             

    1
    $ scp ~/local/file user@remote:~/file

        当然一般我们上传的是文件夹,所以加上-r

    1
    $ scp -r ~/local/file user@remote:~/file

      

     

    3.nginx安装与配置

        首先检查一下远程服务器是否安装ngnix.

    1
    nginx -V

      因为博主的服务器已经安装ngnix,所以下面介绍一下mac os x系统安装nginx的方法

         首先我们要用到homebrew,在终端中输入

      等待安装结束。

         再在终端执行,等待安装结束皆可

    1
    brew install nginx

        brew常用命令:

            安装软件:  brew install  *(软件名 eg. brew install nginx)

            卸载软件:  brew uninstall *

            搜索软件:  brew search *

            显示已经安装软件列表:  brew list

            更新软件:  brew update

            更新某具体软件: brew upgrade git

            

            接下来主要是nginx的配置问题,因为nginx的配置项较多,这里就不一一介绍,只把运行一个静态页面需要配置的东西拿出来配置一下

            首先可以看一下nginx的默认配置,可通过brew查看

            

         从上图中可以看到,nginx的默认root路径(也就是服务器根目录)是 /usr/local/var/www

         默认端口:8080

         下面进入nginx的配置文件,我们也能看到这些信息.

         nginx的配置文件是nginx.conf和nginx.conf.default,一般我们可以从 

         /usr/local/etc/nginx/  中找到这两个文件,通过vim打开nginx.conf。

         可以在配置中看到这样一段,可以在location的root 中改变文件存放位置

       注意:此处有个大坑 

    默认路径事 /usr/local/var/www,而在配置中又写了root html,所以真是路径是 /usr/local/var/www/html

    但我们cd 进入/usr/local/var/www 并没有html文件,所以需要手动创建一个html,并放入工程。

    如果发现nginx没有加载到某些文件或是某些页面出现一下403错误,是因为没有权限

    输入 chmod 755  问题文件路径就可以解决

     

    修改之后需要停止nginx重新启动:终端输入

      nginx -s stop  停止   nginx 重启

     

    4.mac使用cp命令把web文件复制到nginx的路由地址文件

        在上一步我们已经知道了 /usr/local/var/www 是系统运行的根目录,那么我们使用cp命令把我们的本地文件复制到此处

     

    1
    cp -r /local/files /des/files

      

     

    5.浏览工程

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 03:53 , Processed in 0.058067 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表