A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸前端 于 2017-12-27 14:57 编辑

    【南京校区】使用Nginx代理解决前端跨域获取公共API数据DEMO



   各位好,关于前端请求的跨域问题一直是很多学员工作之后面临的一个障碍。
    跨域的概念,大家基本都清楚,当你去请求后台的api时,控制台出现这样的报错,那么就需要解决跨域的问题了

            
   No 'Access-Control-Allow-Origin' header is present on the requested resource   
   跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。注意:跨域限制访问,其实是浏览器的限制。
   我们在学习ajax这个阶段的课程时,给大家的解决方案是jsonp,但是jsonp有一定的现实问题。需要后台开发人员配合去修改接口,可往往你跟后台扯皮半天,人家还是不乐意改,你以为仅仅就是他所说的不规范 不安全??不 其实还有一个重要的原因 ---- 嫌麻烦 他想早点下班。
   那么我们自己来解决这个问题。
   Nginx反向代理服务器解决跨域问题,相信有一些同学已经了解过,对于不太了解的同学,我们先来认识一下什么叫做代理与反向代理。

   正向代理,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。这么看起来有点像翻墙的感觉。用户知道他访问的是什么网站,但是网站不知道是谁真正去访问的它。
   反向代理,就是用户访问了某一个服务器的某个页面,但是实际上这个服务器并没有这个页面,但是这个服务器偷偷从另外一台服务器上取回来,然后作为自己的内容吐给用户,但是用户并不知情。

   说的更简单一点,正向代理为在防火墙内的局域网客户端提供访问Internet的途径反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。
   那么说了这么多,Nginx能干什么,它凭什么能解决跨域问题?
   Nginx是一个反向代理服务器,简单的说,此时我的项目是http://localhost,我想要访问'http://www.xxx.com/api/xxx'
这个接口 如果用传统的方式那么一定会发生跨域的情况,但是如果使用Nginx 我们就可以把http://www.xxx.com/api/xxx这个地址 替换成"/api/xxx" 这样就不存在跨域的问题了。
   下面我们来写一个小demo完成使用Nginx解决跨域的问题。
    1.首先,我们需要安装Nginx
    去Nginx官网下载一个最新版本的Nginx,下载地址:http://nginx.org/en/download.html。我这里下载的版本是:nginx/Windows-1.11.6。下载完成之后,得到一个.zip的压缩包,把压缩包解压到电脑任意盘中 如图:

               2.修改配置文件。打开“conf”文件夹下的“nginx.conf”文件,
     其中server代表启动的一个服务,location 是一个定位规则。
     原本默认就有一个location 如下:

     
[Bash shell] 纯文本查看 复制代码
location /{   #所有以/开头的地址,实际上是所有请求
 
root  html     #去请求../html文件夹里的文件,html文件夹在nginx的根目录中是默认的项目目录
 
index  index.html index.htm  #首页响应地址
 
}

    看出location是nginx用来路由的入口,所以接下来要在location里面完成我们的反向代理。
  我现在的项目位置就在html文件夹下的index.html 也就是http://localhost
     打开cmd定位到Nginx的根目录,输入 start nginx
     然后在浏览器中输入localhost就可以启动项目了
     如图:
    我想要请求的接口地址为"http://v.juhe.cn/weather/index" 一个公共的api 作用是查询天气情况 api信息如图:
   如果我们没有修改Nginx中的配置文件 现在直接请求改接口 会报错提示No 'Access-Control-Allow-Origin' header is present on the requested resource
所以需要修改一下配置文件中的location
   如图:
   
  同时需要修改一下html中ajax的url
  如图:
  
   这里解释一下:
    1.'^~ /weather/ '
  这是一个匹配规则,用于拦截请求,匹配任何以 /weather/开头的地址,匹配符合以后,停止往下搜索正则。
    2.proxy_pass
proxy是Nginx下的一个模块,proxy_pass是该模块下的核心指令,用于指定反向代理服务器的服务器池
当客户端请求 /weather这个路径下的资源时服务器就会帮我们去 http://v.juhe.cn 上取资源,解决了跨域的问题
其中 http://v.juhe.cn/ 写法和 http://v.juhe.cn写法的区别如下:
不带/
[Shell] 纯文本查看 复制代码
location /weather/{
  proxy_pass [url=http://v.juhe.cn]http://v.juhe.cn[/url]; 
}

带/
[Shell] 纯文本查看 复制代码
location /weather/ { 
    proxy_pass [url=http://v.juhe.cn/;]http://v.juhe.cn/;[/url] 
}
上面两种配置,区别只在于proxy_pass转发的路径后是否带 “/”。

  针对情况1,如果访问url = http://localhost/weather/index,则被nginx代理后,请求路径会便问http://v.juhe.cn/weather/index,将weather/作为根路径,请求weather/路径下的资源。
  针对情况2,如果访问url = http://localhost/weather/index,则被nginx代理后,请求路径会变为 http://v.juhe.cn/index,直接访问v.juhe.cn的根资源。

修改配置后重启nginx代理 命令为 nginx -s reload
就成功了。
  






6 个回复

倒序浏览
郭俊峰老师 来自手机 高级黑马 2017-12-27 14:55:00
沙发
很认真的帖子~顶起来
回复 使用道具 举报
666
回复 使用道具 举报
666666
回复 使用道具 举报
阳阳阳 来自手机 初级黑马 2018-3-27 00:20:02
报纸
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
回复 使用道具 举报
茜宝宝Lin 来自手机 初级黑马 2018-3-27 00:22:16
地板
不明觉厉……先码,有空再看
回复 使用道具 举报
oneness 来自手机 初级黑马 2018-3-27 01:46:54
7#
(づ′▽`)づ
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马