ajax跨域请求接口介绍及解决方案

在前端开发过程中,将常出现前端代码和后台服务不在一个服务器的情况,这时候前端js代码调用后台接口,会出现跨域问题。:

1、这里的域是通过URL的头部来识别的。浏览器并不会去尝试判断相同的ip地址对应着两个域或者两个域是否在同一个ip上。URL的头部指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。

2、因为协议、IP、端口造成的跨域问题,只修改前端代码是没用的。

下面我们主要讲述前端和后台服务器不在同一域名下,引起的跨域问题。如果前端js跨域访问后台接口,浏览器控制台会报错。

可用通过两种方式解决:JSONP和CORS。

一、JSONP

JSONP可以实现GET请求的跨域访问。

前端代码:

简写形式,效果相同

后台Java代码:

PrintWriter out = response.getWriter(); JSONObject resultJSON = JSONObject.fromObject(map); //根据需要拼装json String jsonpCallback = request.getParameter("jsonpCallback");//客户端请求参数 out.println(jsonpCallback+"("+resultJSON.toString(1,1)+")");//返回jsonp格式数据

二、CORS

CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。

CORS与JSONP相比,无疑更为先进、方便和可靠。

1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。

使用CORS,需要区分简单请求和预检机制。

在CORS规范中,GET、HEAD和POST这三个HTTP是“简单HTTP方法”,Accept, Accept-Language, Content-Language和报头Content-Type为multipart/form-data、application/x-www-form-urlencoded、text/plain中一种的称为“简单请求报头”。

简单请求:请求采用简单HTTP方法,自定义请求报头空或者自定义请求报头均为简单请求报头。因为具有这些特性的请求不是以更新(添加、修改和删除)资源为目的,服务端对请求的处理不会导致自身维护资源的改变。如果是简单请求,设置Access-Control-Allow-Origin为请求站点IP或者*即可。

预检机制:浏览器在发送真正的跨域资源请求前,先发送一个预检请求(Preflight Request)。预检请求为一个采用HTTP-OPTIONS方法的请求,这是一个不包含主体的请求,同时用户凭证相关的报头也会被剔除。基于真正资源请求的一些辅助授权的信息会包含在此预检请求的相应报头中。

资源的提供者在接收到预检请求之后,根据其提供的相关报头进行授权检验,确定请求站点是否值得信任,请求采用HTTP方法和自定义报头是否被允许。如果预检请求没有通过授权检验,资源提供者一般会返回一个状态为“400, Bad Reuqest”的响应。如果通过,则会返回一个状态为“200, OK”的响应,授权相关信息会包含在响应报头中。除了上面介绍的“Access-Control-Allow-Origin”报头之外,预检请求的响应还具有如下3个典型的报头。

Access-Control-Allow-Methods:跨域资源请求允许采用的HTTP方法列表。

Access-Control-Allow-Headers:跨域资源请求允许携带的自定义报头列表。

Access-Control-Max-Age:浏览器可以将响应结果进行缓存的时间(单位为秒),这样可以让浏览器避免频繁地发送预检请求。

浏览器在接收到预检响应之后,会根据响应报头确定后续发送的真正跨域资源请求是否会被接受,具体的检验逻辑如下:

通过请求的“Origin”报头表示的源站点必须存在于“Access-Control-Allow-Origin”响应报头标识的站点列表中。

l 响应报头“Access-Control-Allow-Methods”不存在,或者预检请求的“Access-Control-Request-Method”报头表示的请求方法在其列表之内。

l 预检请求的“Access-Control-Request-Headers”报头存储的报头名称均在响应报头“Access-Control-Allow-Headers”表示的报头列表之内。

只有在确定服务端一定会接受的情况下,浏览器才会发送真正跨域资源请求。预检响应结果会被浏览器缓存,在“Access-Control-Max-Age”报头设定的时间内,缓存的结果将被浏览器用户进行授权检验,所以在此期间不会再有预检请求发送。

在W3C的CORS规范来说,服务端利用响应报头“Access-Control-Allow-Credentials”来表明自身是否支持用户凭证。这里的用户凭证类型包括Cookie、HTTP-Authentication报头以及客户端X.509证书(采用支持客户端证书的TLS/SSL)等。如果设置“Access-Control-Allow-Credentials”为true,那么“Access-Control-Allow-Origin”不能为”*”,必须是指定的站点。

有预检机制的后台代码设置:

response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");

可以建立一个Filter

package com.chinamobile.cmss.bcse.web.interceptor; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; @Component public class SimpleCORSFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age","3600"); response.setHeader("Access-Control-Allow-Headers","x-requested-with, content-type"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) {} public void destroy() {} }

在web.xml中添加代码:

<filter> <filter-name>cors</filter-name> <filter-class>com.chinamobile.cmss.bcse.web.interceptor.SimpleCORSFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

也可以只修改web.xml。在maven框架中添加maven依赖

<dependency> <groupId>com.thetransactioncompany</groupId> <artifactId>cors-filter</artifactId> <version>2.5</version> </dependency>

web.xml加入配置

<filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param> <param-name>cors.allowOrigin</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>GET, POST, HEAD, PUT, DELETE,OPTION</param-value> </init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value> </init-param> <init-param> <param-name>cors.exposedHeaders</param-name> <param-value>Set-Cookie</param-value> </init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.maxAge</param-name> <param-value>3600</param-value> </init-param></filter> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/*</url-pattern></filter-mapping>

时间: 2024-10-11 05:40:34

ajax跨域请求接口介绍及解决方案的相关文章

JQuery的Ajax跨域请求的解决方案

http://www.open-open.com/lib/view/open1334026513327.html 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式, 于是即刻翻出Jquery的API出来研究,发现JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式.分别是JQuery的 jquery.ajax jsonp格式和jquery.getScript方式. 什么是jsonp

将微博或者qq空间的说说同步至博客园 wcf+js(ajax)跨域请求(1)

前天刚写了篇文章使用Bootstrap为你的博客园自定义轮播图片(今天将图片加载的顺序调整了下,不在访问的时候直接加载,而是页面加载最后在脚本里面动态添加dom元素),虽说技术含量不怎么高,但是大家还算感兴趣.其实对博主来说最关键是博客的积分在涨.所以趁热打铁,再来一篇使用wcf+js ajax跨域请求数据同步空间说说的帖子. 因为是请求qq说说的数据,所以要登陆我的qq,这个很麻烦,总不能让每个访客都登陆的qq,然后把数据取出来吧,而且qq也没有相关的接口提供,登陆的时候还要处理验证码.所以这

ajax跨域请求的处理

跨域的情形有很多种,网上有人给出了一份表格, 表格中标识为"不允许"通信的情况都属于跨域.实际网络服务中需要跨域的情况确实存在,于是开发者们提供了一种解决方案,就是使用jsonp格式进行数据交互,它不是标准的json格式,而是形如"callback(json)"的格式,这样在使用ajax跨域请求的时候就需要对后台的返回值做一下处理,不能返回json数据了. 不跨域时的ajax请求一般是: $.ajax({ type: 'POST', url: "getDa

AJAX跨域请求json数据的实现方法

这篇文章介绍了AJAX跨域请求json数据的实现方法,有需要的朋友可以参考一下 我们都知道,AJAX的一大限制是不允许跨域请求. 不过通过使用JSONP来实现.JSONP是一种通过脚本标记注入的方式,它是可以引用跨域URL的js脚本,不过需要提供一个回调函数(必须在您自己的页面上),因此,你可以自己处理结果. 让我们看看JSONP的是怎么在jQuery,MooTools的,Dojo Toolkit中实现的. jQuery的JSONPjQuery.getJSON方法:Js代码 jQuery.get

JavaScript之Ajax-7 Ajax跨域请求(Ajax跨域概述、Ajax跨域实现)

一.Ajax跨域概述 同源策略 - 同源策略(Same origin policy)是一种约定,它是浏览器的核心也最最基本的核心.如果少了同源策略,则浏览器的正常功能可能都会收到影响.可以说Web是构建在同源策略基础上的,浏览器只是针对同源策略的一种实现 - 它是由 Netscape 提出的一个著名的安全策略 - 现在所有支持 JavaScript 的浏览器都会使用这个策略 - 所谓同源策略是指,域名.协议.端口相同 域名概述 - 域名(Domain Name) 是由一串用点分隔的名字组成的In

jquery ajax跨域请求webservice

有种方式可以通过JSONP方式来请求 这里具体介绍如何通过修改配置文件来实体AJAX跨域请求WEBSERVICE WEBSERVICE的类声名 /// <summary> /// MobileService 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)

调用ajax 跨域调用接口

//ajax 跨域请求数据 function ajaxType (){ $.ajax({ url: "http://127.0.0.1:9090/spring_mvc/HttpClient/ajaxType.do?jsonpCallback=?", type: "GET", data: { pwd: encodeURI('周'), username: 'tl' }, dataType: "jsonp", success: function(dat

JQuery的Ajax跨域请求原理概述及实例

今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发 JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式.分别是JQuery的 jquery.ajax jsonp格式和jquery.getScript方式. 什 么是jsonp格式呢?API原文:如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型

ASP.NET MVC 实现AJAX跨域请求方法《1》

ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据的加载,例如Google. 在ASP.Net MVC 框架里实现跨域的AJAX请求有几种方式可以实现,以下就介绍常用的两种方法. 1.     发送JSONP请求 客户端: jQuery对发送JSONP请求有很好的支持,客户端通过. ajax() 函数发送请求,其中需要制定 dataType 为"j