由于 Javascript 同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制。即会出现跨域请求禁止。

通俗一点说就是如果存在协议、域名、端口或者子域名不同服务端,或一者为IP地址,一者为域名地址(在跨域问题上,域仅仅是通过“ url的首部 ”来识别而不会去尝试判断相同的IP地址对应着两个域或者两个域是否同属同一个IP),之中任意服务端旗下的客户端发起请求其它服务端资源的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。

但很多时候我们却又不得不去跨域请求资源,这个时候就需要我们想方法去绕过浏览器同源策略的限制了。

常见的跨域请求解决方法:

  1.Jsonp 利用script标签发起get请求不会出现跨域禁止的特点实现

  2.window.name+iframe 借助中介属性window.name实现

  3.html5的 postMessage 主要侧重于前端通讯,不同域下页面之间的数据传递

  4.Cors需要服务器设置header:Access-Control-Allow-Origin

  5.Nginx反向代理 可以不需要目标服务器配合,不过需要Nginx中转服务器,用于转发请求(服务端之间的资源请求不会有跨域限制)

下面分别说一下常用几种解决方案的具体实现:

1 Jsonp

一般情况下由于同源策略我们不能够通过XHR跨域去请求资源,但是我们的script标签却可以不受此限制成功的外链到来自于其他域下的资源。利用script标签这个特点,我们可以成功的绕过同源策略。但这种方式存在局限性,我们只能够发起get跨域请求。具体实现:

客户端

服务端

script标签跨域发起get请求,同时传递在客户端已经注册的全局函数 process_fun 作为查询参数,服务端代码提取查询参数,并传入需要返回的数据。script标签还有一个特点,就是会立即执行调用所请求到的资源,所以这个时候服务端返回的 process_fun(data) 这一句代码会被立即执行,即把数据 data 传入我们事先定义好的函数  process_fun 中执行进一步的处理。

2 Cors

即跨域资源共享。实现cors通信的关键是服务器,只要服务器实现了cors接口,就可以跨源通信。不过不同于jsonp,cors对于IE8以下的浏览器是不支持的。

客户端

服务端

跨域资源共享在我看来是最直接也最简便的解决跨域问题的方式了,唯一的缺陷也就只是不能覆盖支持所有的浏览器。客户端不需要去做另外的改变,跟一般状况下发送的异步请求一致就行,甚至客户端根本不需要知道所请求的接口是跨域的。而服务端所需要做的也只是返回响应的同时设置 Access-Control-Allow-Origin 响应头部,意为“予许指定源(‘*’为任意源)发起跨域资源请求”。

3 window.name 和 postMessage 

window.name 和 postMessage 主要都侧重于纯前端页面之间的数据通讯,前者利用了 “ 在同一浏览器窗口载入的不同页面( 无论它们是否不同域 ),共享同一个window.name,并且都对 window.name 有读写的权限 ” 的这一特性来实现页面间的数据交换,后者则是HTML5的API,不同域下的页面在满足一定关系的条件下可以通过此API跨域传送数据。

4 Nginx反向代理

Nginx反向代理解决跨域问题则是利用了服务端之间的资源请求不会有跨域限制的特点实现的,具体来说就是我们前端发起的请求被Nginx拦截,再由Nginx代由转发请求到资源服务器请求资源。

比如现在我们有两个Nodejs服务,分别是http://127.0.0.1:3000 和 http://127.0.0.1:5000,5000端口对应的服务端下的页面需要发起请求3000端口所对应的服务端的资源,当然,在这种情况下如果不做任何的额外处理,请求会产生跨域。这个时候我们可以用Nginx来代理转发我们的请求,前端不去直接对资源服务器发起请求,而是改为直接访问Nginx服务器,看到这里你可能会问了,发起请求的前端页面是属于 http://127.0.0.1:5000 所在域下的,对Nginx服务发起请求难道不会和之前直接发起的请求一样出现跨域吗?所以这里需要明白的一点是,一开始我们可能是通过 http://127.0.0.1:5000/ 这样的路径访问到我们的页面的,但是如果我们使用Nginx作为反向代理,代理服务器监听8080端口,我们这时候再访问该页面就不再是访问 http://127.0.0.1:5000/ , 而是 http://127.0.0.1:8080/ 了,在Nginx中我们再做这样的配置:

location / {
  proxy_pass http://127.0.0.1:5000;
}

就能成功访问到首页了,而这个时候首页是在 8080 端口所对应的域下(即Nginx服务)被渲染出来的,所以首页这个时候便不再与 http://127.0.0.1:5000 同域, 而是与 Nginx 服务同域了,也就是说前端这时候对 Nginx 服务发起请求就不会再是跨域。

访问 Nginx 我们可以实现了,接下来要做的就是对请求进行代理转发。

前端的 Ajax 请求是这样的:

Nginx 需要对该请求进行拦截,所以可以做如下配置:

location配置的意思是对包含 “cross_origin” 请求拦截,并对请求路径进行重写,一开始请求路径是 “/cross_origin/get_json?type=20170126” ,重写后便成了 “/get_json?type=20170126”,$1代表(.*)中的内容,而(.*)则代表 cross_origin 后面的全部字符,也就是我们会把 cross_origin 部分去掉,但是保留 cross_origin 之后的所有字符,当然这一步并非是绝对必要的。接下来我们再把请求代理到 3000 端口所对应的资源服务,所以请求路径从一开始的 “127.0.0.1:8080/cross_origin/get_json?type=20170126” 经过代理服务器Nginx之后变成了 “127.0.0.1:3000/get_json?type=20170126”。在 “127.0.0.1:3000” 下存在对应的接口:

现在在前端触发点击事件发起请求:

得到了响应,至此我们成功发起了跨域请求。

完。

Nginx反向代理、CORS、JSONP等跨域请求解决方法总结的更多相关文章

  1. 使用nginx反向代理处理前后端跨域访问

    本文主要解决:使用nginx反向代理处理前后端跨域访问的问题 1.何为跨域访问? 以下类型为跨域访问 1)不同域名间访问 www.zuiyoujie.com和www.baidu.com 2)同域名不同 ...

  2. WebApi Ajax 跨域请求解决方法(CORS实现)

    概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题, 特别 ...

  3. WebApi Ajax 跨域请求解决方法(CORS实现)(作者:jianxuanbing)

    概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题,特别各 ...

  4. 客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法

    客户端为了实现token认证,通过Jquery的ajaxSetup方法全局配置headers: 全局配置headers后会导致部分不需要token认证的请求变为options请求,导致跨域访问.报错信 ...

  5. 第114天:Ajax跨域请求解决方法(二)

    一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js   http:// (协议号)       www  (子 ...

  6. 第113天:Ajax跨域请求解决方法

    一.原生JS实现ajax 第一步获得XMLHttpRequest对象 第二步:设置状态监听函数 第三步:open一个连接,true是异步请求 第四部:send一个请求,可以发送一个对象和字符串,不需要 ...

  7. 跨域请求解决方法(JSONP, CORS)

    1.跨域 假设我们页面或者应用部署在 http://www.aaa.com 上了,而我们打算从 http://www.bbb.com 请求提取数据.一般情况下,如果我们直接使用 AJAX 来请求将会失 ...

  8. Access to XMLHttpRequest at 'XXX' from origin 'XX' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present o AJAX跨域请求解决方法

    今天出现了一个问题找了好久先看代码: 这可能是个BUG吧插入代码: dataType: 'jsonp', crossDomain: true, 最终:

  9. 关于使用Jsonp做跨域请求

    今天在使用Jsonp做跨域请求的练习时碰上这样一个问题 代码如下 <!DOCTYPE html> <html> <head> <meta charset=&q ...

随机推荐

  1. javascript svg 页面 loading

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. CDOJ 1271 Search gold

    简单DP.dp[i][j]表示走到这格的最大金钱数. #include<cstdio> #include<cstring> #include<cmath> #inc ...

  3. CI框架学习——检查用户名与密码是否合法(二)

    检查用户名与密码是否合法 步骤一.编写用户登录的窗体见下面内容 步骤二.编写数据库校验方法 $username = $_POST["username"];            # ...

  4. 三、MapReduce学习

    MapReducer是一种编程模型,用于大规模数据集(大于1TB)的并行运算.概念"Map(映射)"和"Reduce(化简)"                  ...

  5. ASIHTTPRequest异步请求 分类: ios技术 2015-03-01 09:33 48人阅读 评论(0) 收藏

    我们运行程序,如果网速很慢,查询的时候会一直黑屏,直到请求结束画面才出现,这样用户体验很不好.因此同步请求一般只是在某个子线 程中使用,而不在主线程中使用.异步请求的用户体验要比同步请求好,因此一般情 ...

  6. UWP_小说在线阅读器:功能要求与技术要求

    学了WP开发也有一年了,也没做过什么软件的.17年进发UWP,锻炼自己一下.做一个开源的小说阅读器吧. 既然开发一个软件.所以要设计一下吧. 功能要求: 可能要用到的技术,这个吗,这就是遇到问题在解决 ...

  7. IOS 实现TXT文本自动识别编码的方法

    from :http://kyoworkios.blog.51cto.com/878347/1344013 TXT识别编码是个复杂的问题.幸好有c/c++的一个库能识别. 库的叫uchardet,可以 ...

  8. Ubuntu上搭建Git服务器

    下面我们就看看,如何在Ubuntu上搭建Git服务器.我们使用VMware虚拟机安装两台Ubantu系统,分别命名为gitServer和gitClient_01. 1.安装OpenSSH并配置SSH无 ...

  9. UVA - 140 Bandwidth(带宽)(全排列)

    题意:给定图,求是带宽最小的结点排列. 分析:结点数最多为8,全排列即可.顶点范围是A~Z. #pragma comment(linker, "/STACK:102400000, 10240 ...

  10. 10.TCP连接的建立与终止

      1.建立连接协议 (1)请求端发送一个SYN段指明客户打算连接的服务器的端口,移机初始序号ISN.这个SYN段为报文段1. (2)服务器发回包含服务器的初始序号的SYN报文段作为应答.同时,将确认 ...