返回值处理
不使用修饰
-
ModelAndView
Controller方法中定义ModelAndView对象并返回,对象中可添加model数据,指定view
-
void
在Controller方法形参可以定义request和response,使用request或response指定响应结果
-
使用request转发
request.getRequestDispatcher("页面路径").forward(requset,respose);
-
response重定向
response.sendRedirect("url")
-
response指定响应结果(如json)
response.setCharacterEncoding("usf-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串");
-
-
String
逻辑视图名
return "item/item-list";
-
redirect重定向
return "redirect:textRedirect"
- 相当于"response.sendRedirect()"
- 浏览器URL发生改变
- Request域不能共享
-
forward转发
return "forward:testForward";
- 相当于"request.getRequestDispatcher().forward(requset,respose)"
- 浏览器URL不发生改变
- Request域可以共享
-
使用注解修饰
-
ResponseBody注解介绍
作用:
-
ResponseBody注解可以针对Controller返回值类型,使用内置的9种HttpMessageConverter进行匹配,找到合适的HttpMessageConverter进行处理
-
HttpMessageConverter处理逻辑分为三步
- 指定HttpMessageConverter的ContentType值
- 将转换之后的数据放到HttpMessageConverter对象的响应体
- 返回到页面
-
-
RequestBody注解作用和Response注解正好相反,它是处理请求参数的http消息转换的
-
常用的HttpMessageConverter
-
MappingJacksonHttpMessageConverter
- 作用处理POJO类型返回值
- 默认使用MappingJackson的JSON处理能力,将后台返回的Java对象(POJO类型),转为JSON格式输出到页面
- 将响应体的Content-Type设置为application/json; charset=utf-8
- 调用response.getWriter()方法将json格式的字符串写回给调用者
-
StringHttpMessageConverter
- 作用:处理String类型返回值
- 将响应体的Content-Type设置为text/plain; charset=utf-8
- 调用response.getWriter()方法将Str类型的字符串写回给调用者
-
-
参数绑定
什么是参数绑定
-
定义
将请求参数串的value值获取到之后,再进行类型转换,然后将转换后的值赋给Controller类中方法的形参,这个过程就是参数绑定
- 类型转换(请求中的String类型值---->Con各种数据类型的方法形参)
- 赋值操作,将转换之后的值 赋值给Contr方法形参
-
请求参数格式
默认是key/value格式,比如: http://xxxxx?id=1&type=401
-
请求参数值的数据类型
都是String类型的各种值
-
请求参数值要绑定的目标类型
Controller类中的方法参数,比如简单类型,POJO类型、集合类型等
-
SpringMVC内置的参数解析组件
默认内置了24种参数解析组件(ArgumentResolver)
默认支持的参数类型
Controller方法形参中可以随时添加如下类型的参数(Servlet API支持),处理器适配器自动识别并进行赋值
-
HttpServletRequest
通过request对象获取请求信息
-
HttpServletResponse
通过response处理响应信息
-
HttpSession
通过session对象得到session中存放的对象
-
InputStream、OutputStream
-
Reader、Writer
-
Model/ModelMap
ModelMap继承LinkedHashMap,Model是一个接口,它们的底层实现都是同一个类(BindingAwareModelMap),作用就是向页面传递数据,相当于Request的作用,如下 model.addAttribute("msg","测试springMVC")
参数绑定使用要求
简单类型
-
直接绑定
http请求参数的【key】和controller方法的【形参名称】一致
请求参数的【key】和controller方法的【形参名称】不一致时,需要使用【@RequestParam】注解才能将请求参数绑定成功。
-
RequestParam注解
-
value
参数名字,即入参的请求参数名字,如value="itemid"表示请求的参数
-
required
是否必须,默认是true,表示请求中一定要有相应的参数,否则将报:TTP Status 400 - Required Integer parameter 'XXX' is not present
-
defaultValue
默认值,表示如果请求中没有同名参数时的默认值
-
-
绑定POJO类型
要求表单中【参数名称】和Controller方法中的【POJO形参的属性名称】保持一致
绑定集合或数组类型
-
简单类型数组
通过HTTP请求批量传递简单类型数据的情况,Controller方法中可以用String[]或者pojo的属性接收(两种方式任选其一),但不能使用List集合接收
-
POJO类型集合或数组
批量传递的请求参数,最终要使用List来接收,那么这个List必须放在另一个POJO类中
自定义日期参数绑定
对于springMVC无法解析的参数绑定类型,比如【年月日时分秒格式的日期】绑定到Date类型会报错,此时需要自定义【参数转换器】进行参数绑定。
-
Converter代码
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
- Converter配置
<!-- 加载注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 转换器配置 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean
">
<property name="converters">
<set>
<bean class="com.xxx.ssm.controller.converter.DateConverter"/>
</set>
</property>
</bean>
文件类型参数绑定
SpringMVC文件上传的实现,是由commons-fileupload这个第三方jar包实现的。
-
加入依赖包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
- 上传页面
JSP中的form表单需要指定enctype="multipart/form-data"
-
配置Multipart解析器
在springmvc.xml中配置multipart类型解析器
<!-- multipart类型解析器,文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的最大尺寸 5M-->
<property name="maxUploadSize" value="5242880"/>
</bean>
- Controller类代码
@RequestMapping("fileupload")
public String findUserById(MultipartFile uploadFile) throws Exception {
// 编写文件上传逻辑(mvc模式和三层结构模式)
// 三层模式:表现层(controller、action)、业务层(service、biz)、持久层(dao、
mapper)
// MVC模式主要就是来解决表现层的问题的(原始的表现层是使用Servlet编写,即编写业务逻
辑,又编写视图展示)
if (uploadFile != null) {
System.out.println(uploadFile.getOriginalFilename());
// 原始图片名称
String originalFilename = uploadFile.getOriginalFilename();
// 如果没有图片名称,则上传不成功
if (originalFilename != null && originalFilename.length() > 0) {
// 存放图片的物理路径
String picPath = "E:\\";
// 获取上传文件的扩展名
String extName =
originalFilename.substring(originalFilename.lastIndexOf("."));
// 新文件的名称
String newFileName = UUID.randomUUID() + extName;
// 新的文件
File newFile = new File(picPath + newFileName);
// 把上传的文件保存成一个新的文件
uploadFile.transferTo(newFile);
// 同时需要把新的文件名更新到数据库中
}
}
return "文件上传成功";
}
RequestMapping注解
-
value属性
请求URL映射
-
作用:用于映射URL和HandlerMethod方法
-
用法
- @RequestMapping(value="/item")
- @RequestMapping("/item")
- @RequestMapping(value={"/item","/item2"})
-
-
窄化请求映射
-
作用:限制此类下的所有方法的访问请求url必须以请求前缀开头,对url进行模块分类管理
-
用法:访问时url是/item/findItem
-
@RequestMapping("item")
@Controller
public class ItemController {
@RequestMapping("findItem")
public String findItem(Model model) {
model.addAttribute("msg", "ItemController...findItem方法执行了");
return "success";
}
}
-
method属性
-
作用:限定请求URL只能通过指定的method请求方式去访问该 HandlerMethod
-
用法
- @RequestMapping(value="/findItem",method=RequestMethod.GET)
- @RequestMapping(value="/findItem",method=RequestMethod.POST)
- @RequestMapping(value="/findItem",method={RequestMethod.GET,RequestMethod.POST})
-
-
params属性
-
作用:通过设置 params 参数条件,进行访问 HandlerMethod 的限制
-
用法
- URL请求
<a href="item/removeItem?name=iphone6&price>5000">删除商品,金额大于 5000</a> <br /> <a href="item/removeItem?name=iphoneXs&price>7000">删除商品,金额大于 7000</a>- Controller方法
@RequestMapping(value="removeItem",params= {"name","price>5000"}) public String removeItem(Model model) { model.addAttribute("msg", "ItemController...removeItem方法执行 了"); return "success"; }
-
RESTful支持
HTTP介绍
HTTP协议概述
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。
HTTP协议是建立在客户端和服务器之间的一个应用层协议,在客户端和服务器之间需要数据的传输,而传输数
据的时候,我们要按照指定的规则或者叫协议去传输数据。
URL/URI
-
URI:Uniform Resource Identififier,统一资源标识符
它相当于一个网络资源的名称,只是名称的表现形式是/开头的路径形式
-
URL:Uniform Resource Location,统一资源定位符
-
URL和URI的区别:URL是URI的子集
WEB资源
通过浏览器可以访问到的所有资源都是 web资源 ,web资源分为静态资源和动态资源
- 动态资源是通过后台程序展示页面数据的,比如Servlet请求
- 静态资源的数据是不变的,比如HTML、JPG、AVI
HTTP的作用
就是为了约束客户端和服务器之间传输web资源时的格式
HTTP协议版本
1.0版本和1.1版本
HTTP1.1和HTTP1.0版本之间最大的区别就是:可以一个连接传输多个web资源,推荐使用HTTP1.1版本
HTTP协议组成
HTTP协议由两部分组成:请求协议信息和响应协议信息
-
请求协议信息
HTTP请求协议信息由三部分组成:请求行、请求头、请求体,简称行头体
-
请求行
也叫请求首行,它包含四部分(请求方法、URI、协议/版本、回车换行):
GET /user.html HTTP/1.1
-
请求方法
GET、POST等8种
互联网中WEB资源操作也有增删改查方法,它们分别是POST、DELETE、PUT和GET
-
URI
Uniform Resource Identifier,统一资源标识符。它相当于一个网络资源的名称,只是名称的表现形式是/开头的路径形式
-
协议/版本
表示这次请求是通过哪个协议发送的,比如HTTP协议、HTTPS协议等,使用的HTTP协议一般都是1.1版本的
-
-
请求头
请求头的信息是以[key:value]形式展现的
一般来说,大多数请求头的信息都不是必须的
key value Content-Type 是请求消息中非常重要的内容,表示请求正文中的文档属于什么MIME类型。Content-Type: [type]/[subtype]; parameter。例如最常见的就是text/html,它的意思是说返回的内容是文本类型,这个文本又是HTML格式的 Host 指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回 Accept 浏览器可接受的MIME类型 Accept-Charset 浏览器可接受的字符集 Accept-Encoding 浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间 Accept-Language 浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到 Authorization 授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中 Connection 表示是否需要持久连接。如果Servlet看到这里的值为“Keep- Alive”,或者看到请求使用的是HTTP1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小 Content-Length 表示请求消息正文的长度 Cookie 这是最重要的请求头信息之一,可以在客户端记录访问状态 From 请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它 If-Modifified-Since 只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304"Not Modifified"应答 Pragma 指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝 Referer 包含一个URL,用户从该URL代表的页面出发访问当前请求的页面,使用场景:防盗链、统计网站访问信息 User-Agent 浏览器类型(客户端类型),如果Servlet返回的内容与浏览器类型有关则该值非常有用 UA-Pixels,UA-Color,UA-OS,UA-CPU 由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型 -
请求体
也叫请求正文
- GET请求的请求体是空的,请求参数都是通过请求行转给服务器端
- POST请求的请求体可以承载数据,请求头和请求体之间有一个空行作为分割线
通过表单POST提交的请求体的表现形式主要有三种
值 描述 application/x-www-form-urlencoded 在发送前编码所有字符(默认) multipart/form-data 不对字符编码,在使用包含文件上传控件的表单时,必须使用该值 text-plain 空格转换为"+"加号,但不对特殊字符编码 - application/x-www-form-urlencoded:会对中文进行URL编码,并且多个参数以&连接,上传文件 只能上传文件名称
- text/plain:纯文本方式,不会对中文进行URL编码,不会使用&连接多个key-value参数,上传文件只 能上传文件名称
- multipart/form-data:多部件表现形式,这种方式主要可以完成文件上传,可以将上传的文件名称和 文件内容都传递给服务器端
-
-
响应协议信息
响应协议信息,也由三部分组成:状态行、响应头、响应体(响应正文)
-
状态行
HTTP/1.1 200 OK
状态行由协议/版本、数字形式的状态码、状态描述三部分组成
-
响应头
响应头中的信息也是key value方式展现的。
key value Content-Type 是返回消息中非常重要的内容,表示后面的文档属于什么MIME类型。Content-Type: [type]/[subtype]; parameter。例如最常见的就是text/html,它的意思是说返回的内容是文本类型,这个文本又是HTML格式的。原则上浏览器会根据Content-Type来决定如何显示返回的消息体内容 Location Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源。当我们在JSP中使用重定向语句的时候,服务器端向客户端发回的响应报头中,就会有Location响应报头域 Server Server响应报头域包含了服务器用来处理请求的软件信息。它和User-Agent请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户 端软件(浏览器)和操作系统的信息。下面是Server响应报头域的一个例子:Server:Apache-Coyote/1.1 WWW-Authenticate WWW-Authenticate响应报头域必须被包含在401(未授权的)响应消息中,这个报头域和前面讲到的Authorization请求报头域是 相关的,当客户端收到401响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了 Authorization报头域的请求,下面是WWW-Authenticate响应报头域的一个例子:WWW-Authenticate: Basicrealm="Basic Auth Test!" 从这个响应报头域,可以知道服务器端对我们所请求的资源采用的是基本验证机制 Content-Length 表示响应消息正文的长度 Expires Expires实体报头域给出响应过期的日期和时间。通常,代理服务器或浏览器会缓存一些页面。当用户再次访问这些页面时,直接从缓存中加载并显示给用户,这样缩短了响应的时间,减少服务器的负载。为了让代理服务器或浏览器在一段时间后更新页面,我们可以使用Expires实体报头域指定页面过期的时 间。当用户又一次访问页面时,如果Expires报头域给出的日期和时间比Date普通报头域给出的日期和时间要早(或相同),那么代理服务器或浏览器就 不会再使用缓存的页面而是从服务器上请求更新的页面。不过要注意,即使页面过期了,也并不意味着服务器上的原始资源在此时间之前或之后发生了改变。 Last-Modified Last-Modified实体报头域用于指示资源最后的修改日期及时间 Set-Cookie 设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie",...),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论 Allow 服务器支持哪些请求方法(如GET、POST等) Content-Encoding 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看AcceptEncoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面 -
响应体
响应体,也叫响应正文,里面包含服务器发给客户端的web资源信息。
响应正文信息返回到浏览器时,浏览器需要根据响应头中Content-type设置的MIME类型来打开响应正文信息
-
RESTful介绍
REST
REST(英文:Representational State Transfer,简称 REST,意思是:(资源)表述性状态转化) 描述了一个架构样式的网络系统, 比如 web 应用程序
它是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和 服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制
它本身并没有什么实用性,其核心价值在于如何设计出符合 REST 风格的网络接口
RESTful
REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful
RESTful的特性
-
资源(Resources)
-
网络上的一个实体,或者说是网络上的一个具体信息
-
它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在
-
可以用一个 URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的 URI 就可以,因此 URI 即为每一个资源的独一无二的识别符
-
-
表现层(Representation)
- 把资源具体呈现出来的形式,叫做它的表现层 (Representation)
- 比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进 制格式
-
状态转化(State Transfer)
- 每发出一个HTTP请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的 【状态】都保存在服务器端。因此,如果客户端想要操作服务器, 必须通过某种手段,让服务器端发生“状态 转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “ 表现层状态转化”
- 具体说, 就是 HTTP 协议里面,四个表示操作方式的动词:GET 、POST 、PUT 、DELETE 。它们分别对 应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源
设计RESTful应用程序的API
- 路径设计:数据库设计完毕之后,基本上就可以确定有哪些资源要进行操作,相对于的路径也可以设计出来
- 动词设计:也就是针对资源的具体操作类型,由HTTP动词表示,常用的HTTP动词如下:POST、DELETE、 PUT、GET
RESTful 的示例
- /account/1 HTTP GET : 得到 id = 1 的 account
- /account/1 HTTP DELETE: 删除 id = 1 的 account
- /account/1 HTTP PUT: 更新 id = 1 的 account
SpringMVC对RESTful的支持
RESTful的URL路径变量
-
URL-PATTERN :设置为/,方便拦截 RESTful 请求
<servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> -
@PathVariable:可以解析出来URL中的模板变量({id})
-
URL
http://localhost:8080/ssm/item/1/zhangsan -
Controller
@RequestMapping(“{id}/{name}”) @ResponseBody public Item queryItemById(@PathVariable Integer id, @PathVariable String name){ }
-
静态资源
如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理 在springmvc.xml文件中,使用 mvc:resources 标签,具体如下
<!-- 当DispatcherServlet配置为/来拦截请求的时候,需要配置静态资源的访问映射 -->
<mvc:resources location="/js/" mapping="/js/"/>
<mvc:resources location="/css/" mapping="/css/"/>
SpringMVC 会把 mapping 映射到ResourceHttpRequestHandler,这样静态资源在经过DispatcherServlet 转发时就可以找到对应的 Handler了
拦截器应用
拦截器介绍
-
SpringMVC 的拦截器主要是针对特定处理器进行拦截的
-
SpringMVC 拦截器( Interceptor )实现对每一个请求处理前后进行相关的业务处理,类似与servlet 中的Filter
-
SpringMVC 中的 Interceptor 拦截请求是通过 HandlerInterceptor 接口来实现的
在 SpringMVC 中定义一个 Interceptor 非常简单,主要有4种方式
- 实现 SpringMVC 的 HandlerInterceptor 接口
- 继承实现了 HandlerInterceptor 接口的类,比如 SpringMVC 已经提供的实现了HandlerInterceptor 接口的抽象类 HandlerInterceptorAdapter
- 实现 SpringMVC 的 WebRequestInterceptor 接口
- 继承实现了 WebRequestInterceptor的类
定义拦截器
实现 HandlerIntercepter 接口
public class MyHandlerIntercepter implements HandlerInterceptor{
//Handler执行前调用
//应用场景:登录认证、身份授权
//返回值为true则是放行,为false是不放行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
//进入Handler开始执行,并且在返回ModelAndView之前调用
//应用场景:对ModelAndView对象操作,可以把公共模型数据传到前台,可以统一指定视图
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { }
//执行完Handler之后调用
//应用场景:统一异常处理、统一日志处理
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
}
配置拦截器
SpringMVC 拦截器是绑定在 HandlerMapping 中的,即:如果某个 HandlerMapping 中配置拦截,则该 HandlerMapping 映射成功的 Handler 会使用该拦截器
SpringMVC 的全局拦截器配置,其实是把配置的拦截器注入到每个已初始化的 HandlerMapping 中了
<!-- 配置全局mapping的拦截器 -->
<mvc:interceptors>
<!-- 公共拦截器可以拦截所有请求,而且可以有多个 -->
<bean class="com.xxx.ssm.interceptor.MyHandlerInterceptor" />
<bean class="com.xxx.ssm.interceptor.MyHandlerInterceptor2" />
<!-- 如果有针对特定URL的拦截器,则进行以下配置 -->
<mvc:interceptor>
<!-- /**表示所有URL和子URL路径 -->
<mvc:mapping path="/orders/**" />
<!-- 特定请求的拦截器只能有一个 -->
<bean class="com.xxx.ssm.interceptor.MyHandlerInterceptor3" />
</mvc:interceptor>
</mvc:interceptors>
多拦截器拦截规则
如果有多个拦截器,那么配置到springmvc.xml中最上面的拦截器,拦截优先级最高
CORS跨域解决方案
跨域介绍
浏览器因为安全考虑,所以设置了同源策略。同源策略简单理解就是DNS域名,端口号,协议完全相同就称为同源。同源下的页面之间才能进行js的dom操作,如果不在一个源下任何跨文档dom访问都是被阻止的。不同源下的访问可以称之为跨域访问
CORS
-
CORS 是一个 W3C 标准,全称是"跨域资源共享"( Cross-origin resource sharing )
-
它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制
-
CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能, IE 浏览器不能低于IE10
-
CORS 原理
- 客户端自动向请求头 header 中注入 Origin
- 服务器端需要向响应头 header 中注入 Access-Control-Allow-Origin
- 浏览器检测到 header 中的 Access-Control-Allow-Origin ,则就可以跨域操作了
客户端跨域处理
请求分类标准
浏览器将 CORS 请求分成两类:简单请求( simple request )和非简单请求( not-so-simple request )
同时满足以下两大条件,就是属于简单请求
-
请求方法是一下三种方法之一:
- HEAD
- GET
- POST
-
HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求
简单请求
对于简单请求,浏览器直接发出 CORS 请求。具体来说,就是在头信息之中,增加一个 Origin 字段
非简单请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是 PUT 或 DELETE ,或者 Content-Type字段的类型是 application/json
非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,称为"预检"请求( preflight )
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信 息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。