在某域名下使用ajax向另一个域名下的地址请求数据时,浏览器出于安全考虑,会限制在脚本中发起的跨域请求。然而怎样才能算跨域?协议,域名,端口都必须相同,才算在同一个域。也就是说如果协议、域名、端口中有一个不同,就是在不同的域。

例如我现有一个jsp页面,http://localhost:8080/domainReq/index.jsp,若用ajax请求下面地址的服务时,会出现跨域问题。

地址 端口 跨域
http://100.111.10.48:8080/ 8080 地址不同
http://localhost:8080 8080 地址、端口相同,可以请求。
http://localhost:8081 8081 端口不同
https://100.111.10.48:8080 8080 协议不同

例外:由于JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。这里不考虑JSONP。
HTML5带来了一个新的跨域解决方案CORS,CORS是一个W3C标准,全称是”跨域资源共享”(Cross-Origin Resource Sharing)。具体看百科

CROS header简单的描述

标头 描述
Access-Control-Allow-Origin 多个域名可以用逗号隔开。如www.ios.com,www.android.com。*表示谁都可以,不限制域名(不建议使用)。
Access-Control-Expose-Headers 设置浏览器允许访问的服务器的头信息的白名单
Access-Control-Max-Age 在CROS协议中,一个AJAX请求被分成了两步。第一步OPTION为预检测请求,第二步为正式请求。请求的结果的有效期是多久,单位秒。
Access-Control-Allow-Credentials 是否允许请求带有验证信息
Access-Control-Allow-Methods 资源可以被哪些方式请求GET, POST,TRACE等,多个值时用逗号分开,*为不受限制。
Access-Control-Allow-Headers 允许自定义的头部,逗号隔开。如:Content-Type, x-requested-with, Authorization等。

比如:Access-Control-Allow-Headers,若ajax请求时header带了Authorization令牌,而这里又未设置时会出现(已拦截跨源请求:同源策略禁止读取位于 http://100.111.10.48:8080/domain/MyServlet 的远程资源。(原因:来自 CORS 预检通道的 CORS 头 ‘Access-Control-Allow-Headers’ 的令牌 ‘authorization’ 无效)。)


下面来看看ajax调用跨域服务,和服务端分别通过spring mvc 注解方式或Servlet + Filter 方式发布服务。

1.请求示例
客户端IP为100.111.10.17

2.未设置Response Headers时
btn1事件引用的地址并没有设置任何Response Headers信息。
返回错误信息:XMLHttpRequest cannot load http://100.111.10.48:8080/domain/MyServlet. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8080’ is therefore not allowed access.

3.设置Response Headers时
btn2事件引用的地址,Response Headers设置了Access-Control等信息。可以成功返回结果,已经打印出信息了。
在这里发现会请求两次,第一次Method为OPTIONS,第二次为POST。这是因为在做跨域请求时浏览器会自动发起一个 OPTIONS 到服务器,是一种预检测请求,用来检测是否安全。
从服务器返回的headers中,可以看到分别设置了CROS 各种信息:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:x-requested-with,Authorization
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:http://localhost:8080
Access-Control-Max-Age:10
Allow:GET, HEAD, POST, TRACE, OPTIONS
Content-Length:0
Date:Thu, 01 Dec 2016 08:36:36 GMT
Server:Apache-Coyote/1.1

4.后台服务

1.采用Spring CrossOrigin

CrossOrigin注解在spring mvc 4.2 之上才有的特性。可参考http://spring.io/blog/2015/06/08/cors-support-in-spring-framework

@RestController
@RequestMapping(value = "/helloworld")
public class HelloController {/*** CrossOrigin注解在spring mvc 4.2* @param id* @param request* @param response* @return*/@CrossOrigin(origins = "http://localhost:8080", maxAge = 10)@RequestMapping(value = "/rest/{id}", method = { RequestMethod.POST, RequestMethod.GET })public Message getms(@PathVariable int id, HttpServletRequest request, HttpServletResponse response) {System.out.println("---------------rest/" + id + " request-------------");System.out.println(request.getHeader("Authorization"));System.out.println(request.getHeader("x"));Message message = new Message();message.setId(Integer.toString(id));message.setName("123");message.setText("hello,123");return message;}
}
2.过滤器方式

Filter

public class CORSFilter implements Filter {@Overridepublic void destroy() {System.out.println("Filter-destroy");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {//String origin = (String) servletRequest.getRemoteHost()+":"+servletRequest.getRemotePort();HttpServletRequest request = (HttpServletRequest) servletRequest;System.out.println("Filter-Method:" + request.getMethod()); // GET, POST, OPTIONSSystem.out.println("Filter-Authorization:" + request.getHeader("Authorization"));HttpServletResponse response = (HttpServletResponse) servletResponse;response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "10");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");response.setHeader("Access-Control-Allow-Credentials", "true");filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void init(FilterConfig arg0) throws ServletException {System.out.println("Filter-init");}
}

Servlet

/*** Servlet implementation class MyServlet*/
public class MyServlet extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public MyServlet() {super();}@Overridepublic void init() throws ServletException {super.init();System.out.println("Servlet-init");}@Overridepublic void destroy() {super.destroy();System.out.println("Servlet-destroy");}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {       System.out.println("Servlet-Method:" + request.getMethod());System.out.println("Servlet-Authorization:" + request.getHeader("Authorization"));response.getWriter().append("{\"CTY\": \"china\"}");response.getWriter().close();}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}

ajax 跨域 CROS相关推荐

  1. 让 QtWebkit 支持跨域CROS - nowboy的CSDN博客 - 博客频道 - CSDN.NET

    让 QtWebkit 支持跨域CROS - nowboy的CSDN博客 - 博客频道 - CSDN.NET 让 QtWebkit 支持跨域CROS 2013-05-23 22:05 450人阅读 评论 ...

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

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

  3. HTML5 AJAX跨域请求

    方法一:HTML5新的标准中,增加了" Cross-Origin Resource Sharing"特性,这个特性的出现使得跨域通信只需通过配置http协议头来即可解决. Cros ...

  4. 如何解决ajax跨域java,ajax跨域问题,从java角度解决

    前言 今天给小伙伴开放一个接口方便调试数据,但是老是出现CROS策略阻塞,查询资料后知道了是ajax跨域引起的,以此记录此次解决问题的过程. 什么是ajax跨域 ajax跨域的原理 ajax出现请求跨 ...

  5. ajax跨域请求传递Cookie问题

    问题描述 前后端完全分离的项目,前端使用Vue + axios,后端使用SpringMVC,容器为Tomcat. 使用CORS协议解决跨域访问数据限制的问题,但是发现客户端的Ajax请求不会自动带上服 ...

  6. Jetty Cross Origin Filter解决jQuery Ajax跨域访问的方法

    当使用jQuery Ajax post请求时可能会遇到类似这样的错误提示 XMLHttpRequest cannot load http://xxxxxx. Origin http://xxxxxx ...

  7. Ajax跨域:Jsonp原理解析

    推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...

  8. js请求结果拦截机器_js利用jquery的jsonp来解决ajax跨域请求被浏览器拦截结果的问题...

    先来个表.页面太多对不起我也不知道这张表是从哪个博客保存过来的,所以无法注明博客地址.非常抱歉.URL说明是否允许通信 http://www.a.com/a.jshttp://www.a.com/b. ...

  9. ajax跨域问题解决方案

    今天来记录一下关于ajax跨域的一些问题.以备不时之需. 跨域 同源策略限制 同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性.也就是说,受到请求的 URL 的域必须与当前 Web 页面 ...

最新文章

  1. 第二天2017/03/29: 字符串操作
  2. UML--9种图及关系
  3. 软件测试推荐专业,软件测试专业老师推荐信
  4. LeetCode 1487. 保证文件名唯一(哈希map)
  5. dsp 链接命令文件的写法
  6. Please Select android SDK的解决办法
  7. UE4 视差毛发材质
  8. 极限压缩----压缩至原视频的五分之一
  9. [视频]AI 机器学习 深度学习 视频教程汇总
  10. 计算机考试画箭头,word绘图教程:画箭头、大括号、曲线等常用自选图形-word技巧-电脑技巧收藏家...
  11. composer init 命令详解
  12. 什么是MES系统?MES系统具备哪些优势?
  13. protobuffer
  14. CUDA Installer 前面的 X
  15. 计算机专业、物联网工程大一寒假规划必备篇
  16. 基于RFID军用物资管理系统-RIFD战备物资仓库管理系统
  17. web HTML5新标签对IE低版本浏览器的兼容处理
  18. Linux使用Docker安装Nacos并配置MySQL数据源,将Springboot的配置文件部署到Nacos
  19. PS的快速入门与使用教程
  20. 链脉课堂:这是一份抖音营销快速入门教程

热门文章

  1. c#中使用Aspose.Word组件,将数据和图片导出至Word
  2. 2021PAT甲级春季考试题解 AC
  3. 前端项目写入数据库中文乱码
  4. 手把手Java爬虫教学 - 2. 爬虫项目创建 需求说明
  5. 黑马程序员__关于自己的一些学习死角的再学习(基于老毕的java基础视频)
  6. Linux下安装kettle及作业调度
  7. 苏嵌//杨曼曼//0723
  8. 虚拟机ubuntu连不上网
  9. app功能性测试——安装卸载升级测试、交叉事件测试、通知推送测试
  10. 7天使用感受 惠普 6515b GP169 笔记本