求vue解决跨域问题题

js跨域请求的5中解决方式
当前位置: >
> js跨域请求的5中解决方式js跨域请求的5中解决方式更新:&&&&编辑:幼薇&&&&来源:转载&&&&人气:加载中...&&&&字号:|标签:&&&&&&&&
数据方案主要有如下法子:
服务器代理
Html5的XDomainRequest
Flash request
分开说明:
一、JSONP:
直观的理解:
就是在动态一个函数
function a(data),然后将函数名传到服务器,服务器返回一个a({/*json*/})到运行,这样就调用客户端的
function a(data),从而实现了.
诞生背景:
1、Ajax直接普通文件存在跨域无权造访的,甭管是静态页面、动态网页、web服务、wcf、只要是跨域请求,一律不行。
2、不过,web页面上调用js文件时则不受此影响
3、进一步推广,我们发现,凡是拥有Src属性的都有跨域能力,如:&script&&img&&iframe&
4、于是,当前如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域造访数据,就只能如下方式:就是在远程服务器上设法把数据装进js款式的文本里,供客户端调用和进一步处理。
5、JSON就是一种纯字符数据款式,且能呗js原生支持。
6、这样方案出炉:web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js款式文件(一般以json为后缀)。
7、客户端在对json文件调用成功后,也就得到了所需数据,剩下的就是遵照自己的需求进行处理了。
8为了便于客户端数据,逐渐形成了一种非正式的传输协议,称之为jsonp。该协议的一个要点就是允许用户传递一个callback参数给服务器,然后服务器返回数据时会将这个callback参数作为函数名来包裹住json数据,这样客户端就可以随意定制自己的函数来处理返回数据了。
具体实现:
不管jQuery也好,extjs也罢,又或者是其他支持jsonp的框架,他们幕后所做的工作都是一样的,下面我来循序渐进的说明一下jsonp在客户端的实现:
1、我们,哪怕跨域js文件中的代码(当然指符合web脚本安全策略的),web页面也是可以无条件履行的。
远程服务器根下有个remote.js文件代码如下:
alert('我是远程文件');
本地服务器下有个jsonp.html页面代码如下:
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&title&&/title&
&script type="text/javascript" src="/remote.js"&&/script&
毫无疑问,页面将会弹出一个提示窗体,显示跨域调用成功。
2、现在我们在jsonp.html页面定义一个函数,然后在远程remote.js中传入数据进行调用。
jsonp.html页面代码如下:
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&title&&/title&
&script type="text/javascript"&
var localHandler = function(data){
alert('我是本地函数,,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
&script type="text/javascript" src="/remote.js"&&/script&
remote.js文件代码如下:
localHandler({"result":"我是远程js带来的数据"});
运行之后查看结果,页面成功弹出提示窗口,显示本地函数被跨域的远程js调用成功,并且还接管到了远程js带来的数据。很欣喜,跨域远程获取数据的目的基本实现了,但是又一个出现了,我怎么让远程js它应该调用的本地函数叫什么名字呢?终究是jsonp的服务者都要面对很多服务对象,而这些服务对象各自的本地函数都不相同啊?我们接着往下看。
3、聪明的开发者很容易想到,只要服务端供给的js脚本是动态生成的就行了呗,这样调用者可以传一个参数过去奉告服务端“我想要一段调用XXX函数的js代码,请你返回给我”,于是服务器就可以遵照客户端的需求来生成js脚本并响应了。
看jsonp.html页面的代码:
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&title&&/title&
&script type="text/javascript"&
// 得到航班信息查询结果后的回调函数
var flightHandler = function(data){
alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
// 供给jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
var url = "/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 创建script,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
这次的代码变更对比大,不再直接把远程js文件写逝世,而是编码实现动态查询,而这也正是jsonp客户端实现的核心部分,本例中的重点也就在于如何完成jsonp调用的全历程。
我们看到调用的url中传递了一个code参数,奉告服务器我要查的是CA1998次航班的信息,而callback参数则奉告服务器,我的本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
我们看到,传递给flightHandler函数的是一个json,它描述了航班的基本信息。运行一下页面,成功弹出提示窗口,jsonp的履行全历程顺利完成!
4、到这里为止的话,信任你已经能够理解jsonp的客户端实现原理了吧?剩下的就是如何把代码封装一下,以便于与用户界面交互,从而实现多次和重复调用。
什么?你用的是jQuery,想知道jQuery如何实现jsonp调用?好吧,那我就好人做到底,再给你一段jQuery应用jsonp的代码(我们依然沿用上面那个航班信息查询的例子,假定返回jsonp结果不变):
OK,服务器很聪明,这个叫做flightResult.aspx的页面生成了一段这样的代码供给给jsonp.html(服务端的实现这里就不演示了,与你选用的语言无关,说到底就是拼接字符串):
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
分类选择您可能在找这些帮设计师节省1,085,543,232小时502 Bad Gateway
502 Bad Gateway
openresty/1.11.2.22017年8月 总版技术专家分月排行榜第一
2016年2月 总版技术专家分月排行榜第二2014年2月 总版技术专家分月排行榜第二2013年4月 总版技术专家分月排行榜第二
2017年8月 总版技术专家分月排行榜第一
2016年2月 总版技术专家分月排行榜第二2014年2月 总版技术专家分月排行榜第二2013年4月 总版技术专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。解决跨域请求问题 - CSDN博客
解决跨域请求问题
随着Web开放的程度越来越高,通过浏览器跨域获取资源的需求已经变得非常普遍。在我看来,如果Web API不能针对浏览器提供跨域资源共享的能力,它甚至就不应该被称为Web API。从另一方面来看,浏览器作为进入Internet最大的入口,是各大IT公司的必争之地,所以浏览器市场出现了种类繁多、鱼龙混杂的局面。针对这两点,我们迫切需要一种能够被各个浏览器厂商共同遵循的标准来对跨域资源共享作出规范,这就是由W3C指定2的CORS(Cross-Origin Resource Sharing)规范。
CORS是如何工作的?
对响应报头的授权
是否支持用户凭证
一、CORS是如何工作的?
基于Web的资源共享涉及到两个基本的角色,即资源的提供者和消费者。针对我们前面演示的应用场景,即显示在浏览器中的某个Web页面通过调用Web API的方式来获取它所需的资源,资源提供者为Web API本身,通过发送Ajax请求来调用Web API的JavaScript程序为资源的消费者。
CORS旨在定义一种规范让浏览器在接收到从提供者获取的资源时能够正决定是否应该将此资源分发给消费者作进一步处理。CROS利用资源提供者的显式授权来决定目标资源是否应该与消费者共享。换句话说,浏览器需要得到提供者的授权之后才会将其提供的资源分发给消费者。那么,资源的提供者如何进行资源的授权,并将授权的结果告诉浏览器呢?
具体的实现其实很简单。如果浏览器 自身提供对CROS的支持,由它发送的请求会携带一个名为“Origin”的报头表明请求页面所在的站点。对于中调用Web API获取联系人列表的请求来说,它就具有如下一个“Origin”报头。
1: Origin: http://localhost:9527
资源获取请求被提供者接收之后,它可以根据该报头确定提供的资源需要共享给谁。资源提供者的授权通过一个名为“Access-Control-Allow-Origin”的响应报头来承载,其报头值表示得到授权的站点。一般来说,如果资源的提供者认可了当前请求的“Origin”报头携带的站点,那么它会将该站点作为“Access-Control-Allow-Origin”响应报头的值。
除了指定具体的源并对其作针对性授权之外,资源提供者还可以将“Access-Control-Allow-Origin”报头值设置为“*”对所有消费者授权。换言之,如果作了这样的设置,意味着由其提供的是一种公共资源,所以在做此设置之前需要慎重。如果针对请求着的授权不被允许,资源提供者可以将此响应报头值设置为“null”,或者让响应不具有此报头。
当浏览器接收到包含资源的响应之后,会提取此“Access-Control-Allow-Origin”响应报头的值。如果此值为“*”或者包含的源列表包含此前请求的源(即请求的“Origin”报头值),意味着资源的消费者获取了提供者获取和操作资源的权限,所以浏览器会允许JavaScript程序操作获取的资源。如果此响应报头不存在或者其值为“null”,客户端JavaScript程序针对资源的操作会被拒绝。
二、对响应报头的授权
资源提供者除了通过设置“Access-Control-Allow-Origin”报头对提供的主体资源进行授权之外,还可以通过设置另一个名为“Access-Control-Expose-Headers”的报头对响应报头进行授权。具体来说,此“Access-Control-Expose-Headers”的报头用于设置一组直接暴露给客户端JavaScript程序的响应报头,没有在此列表的响应报头 对于客户端JavaScript程序是不可见的。
但是由此实现的针对响应报头的授权针对简单响应报头是无效的,客户端JavaScript程序总是具有获取它们的权限。对于CORS规范来说,这里所谓的“简单响应报头(Simple Response Header)”包含如下6种。
Cache-Control Content-Language Content-Type Expires Last-Modified Pragma
我们知道用于实现Ajax请求的XMLHttpRequest具有一个getResponseHeader方法,调用它会返回一组响应报头的列表。按照这里介绍的针对响应报头的授权原则,只有在“Access-Control-Expose-Headers”报头中指定的报头和简单响应报头才会包含在该方法返回的列表中。
三、预检机制
W3C的CORS规范将跨域资源请求划分为两种类型,一种被称为“简单请求(Simple Request)”。要弄清楚CORS规范将那些类型的跨域资源请求划分为简单请求的范畴,需要额外了解几个名称的含义,其中包括“简单(HTTP)方法(Simple Method)”、“简单(请求)报头(Simple Header)”和“自定义请求报头(Author
Request Header/Custom Request Header)”。
CORS规范将GET、HEAD和POST这三个HTTP方法视为“简单HTTP方法”,而将请求报头Accept, Accept-Language, Content-Language以及采用如下三种媒体类型的报头Content-Type称为“简单请求报头”
application/x-www-form-urlencoded multipart/form-data text/plain
请求的报头包含两种类型,一类是通过浏览器自动生成的报头,另一种则是由JavaScript程序自行添加的报头(比如调用XMLHttpRequest的setRequestHeader方法可以为生成的Ajax请求添加任意报头),后者被称为“自定义报头”。
CORS规范将服务如下条件的跨域资源请求划分为简单请求:请求采用简单HTTP方法,并且其自定义请求报头空或者所有自定义请求报头均为简单请求报头。之所以作如此划分是因为具有这些特性的请求不是以更新(添加、修改和删除)资源为目的,服务端对请求的处理不会导致自身维护资源的改变。
对于简单跨域资源请求来说,浏览器将两个步骤(取得授权和获取资源)合二为一,由于不涉及到资源的改变,所以不会带来任何副作用(Side Effect)。如果针对请求的处理过程会涉及到对资源的改变,这样做就会有问题了。按照CORS规范的规定,浏览器应该采用一种被称为“预检(Preflight)”的机制来完成非简单跨域资源请求。
所谓预检机制就是说浏览器在发送真正的跨域资源请求前,先发送一个预检请求(Preflight Request)。预检请求为一个采用HTTP-OPTIONS方法的请求,这是一个不包含主体的请求,同时用户凭证相关的报头也会被剔除。基于真正资源请求的一些辅助授权的信息会包含在此预检请求的相应报头中。除了代表请求页面所在站点的“Origin”报头之外,如下所示的是两个典型的请求报头。
Access-Control-Request-Method:真正跨域资源请求采用的HTTP方法。 Access-Control-Request-Headers:真正跨域资源请求携带的自定义报头列表。
资源的提供者在接收到预检请求之后,根据其提供的相关报头进行授权检验,具体的检验逻辑即包括确定请求站点是否值得信任,以及请求采用HTTP方法和自定义报头是否被允许。如果预检请求没有通过授权检验,资源提供者一般会返回一个状态为“400, Bad Reuqest”的响应。反之则会返回一个状态为“200, OK”的响应,授权相关信息会包含在响应报头中。除了上面介绍的“Access-Control-Allow-Origin”和“Access-Control-Expose-Headers”报头之外,预检请求的响应还具有如下3个典型的报头。
Access-Control-Allow-Methods:跨域资源请求允许采用的HTTP方法列表。 Access-Control-Allow-Headers:跨域资源请求允许携带的自定义报头列表。 Access-Control-Max-Age:浏览器可以将响应结果进行缓存的时间(单位为秒),这样可以让浏览器避免频繁地发送预检请求。
浏览器在接收到预检响应之后,会根据响应报头确定后续发送的真正跨域资源请求是否会被接受,相关的检验包括针对服务端允许站点以及HTTP方法和自定义请求报头(利用响应报头“Access-Control-Allow-Methods”和“Access-Control-Allow-Headers”)的检验。具体的检验逻辑如下
通过请求的“Origin”报头表示的源站点必须存在于“Access-Control-Allow-Origin”响应报头标识的站点列表中。 响应报头“Access-Control-Allow-Methods”不存在,或者预检请求的“Access-Control-Request-Method”报头表示的请求方法在其列表之内。
预检请求的“Access-Control-Request-Headers”报头存储的报头名称均在响应报头“Access-Control-Allow-Headers”表示的报头列表之内。
只有在确定服务端一定会接受的情况下,浏览器才会发送真正跨域资源请求。预检响应结果会被浏览器缓存,在“Access-Control-Max-Age”报头设定的时间内,缓存的结果将被浏览器用户进行授权检验,所以在此期间不会再有预检请求发送。
四、是否支持用户凭证
在默认情况下,利用XMLHttpReuqest发送的Ajax请求不会携带用户凭证相关的敏感信息,这里的用户凭证类型包括Cookie、HTTP-Authentication报头以及客户端X.509证书(采用支持客户端证书的TLS/SSL)等。如果需要用户凭证附加到Ajax请求上,需要将XMLHttpReuqest的withCredentials 属性设置为True。
对于CORS来说,是否支持用户凭证也是授权检验的一个环节。换句话说,只有在服务端显式支持用户凭证的情况下,携带了用户凭证的请求才会被认为是有效的。在W3C的CORS规范来说,服务端利用响应报头“Access-Control-Allow-Credentials”来表明自身是否支持用户凭证。
也就是说,如果客户客户端JavaScript程序利用一个withCredentials属性为true的XMLHttpReuqest发送了一个跨域资源请求,但是浏览器得到的响应中不具有一个值为“true”的响应报头“Access-Control-Allow-Credentials”,它对获取资源的操作将会浏览器拒绝。
上面我们对W3C的CORS规范作了概括性的介绍,由于篇幅所限,很多的细节并没有涉及。如果读者朋友们对此有兴趣,我个人强烈推荐直接阅读W3C的官方文档。由于官方文档的文字描述较为“生硬”,可能需要多读几遍才能将资源提供者和浏览器如何处理资源授权流程搞清楚。
本文已收录于以下专栏:
相关文章推荐
传统的跨域请求没有好的解决方案,无非就是jsonp和iframe,随着跨域请求的应用越来越多,W3C提供了跨域请求的标准方案(Cross-Origin
Resource Sharing)。IE8、...
解决Ajax请求跨域问题
398人阅读 评论(1)
本文章已收录于:
【HTTP】(2)
最近几天碰到了跨域请求问题,
有时候工作中我们需要从A网站访问B网站请求数据,但是这种方式浏览器是拒绝的,jquery的ajax为我们提供了一种解决办法,那就是通过标签进行包装,因为您标签是能实现跨域访问的,下面讲解具体的用法。
...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Java&前后端分离跨域请求问题
CrossFilter 类
** * 跨域操作拦截器(在服务器返回信息后处理) */@Componentpublic class CrossFilter extends OncePerRequestFilter {
@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
response.setHeader("Access-Control-Max-Age", "1800");//30 minfilterChain.doFilter(request, response);
web.xml,不知道为什么会有"span标签"
&&/SPAN&filter&
&&/SPAN&filter-name&cros&/&/SPAN&filter-name&
&&/SPAN&filter-class&cn.thinkjoy.qky.portal.filter.CrossFilter&/&/SPAN&filter-class&
&/&/SPAN&filter&
&&/SPAN&filter-mapping&
&&/SPAN&filter-name&cros&/&/SPAN&filter-name&
&&/SPAN&url-pattern&/*&/&/SPAN&url-pattern&
&/&/SPAN&filter-mapping&
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 nginx解决跨域问题 的文章

 

随机推荐