实现 伪静态
创建配置类
package com.jt.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfigurer implements WebMvcConfigurer{//等同web项目中的web.xml配置文件
//可以拦截后缀加上(。html)的路径
//开启匹配后缀型配置 伪静态 忽略后缀进行匹配路径匹配
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
}
}
京东页面分析
思考: 当前的页面是在后端服务器中真实存在的,还是由一个页面动态填充数据实现的!!!
说明: 经过分析 京东的商品的展现由一个页面动态的填充. 只要服务器接收商品ID即可.并且应该拦截.html为后缀的页面请求.
什么是伪静态
伪静态是相对真实静态来讲的,通常我们为了增强搜索引擎的友好面,都将文章内容生成静态页面,但是有的朋友为了实时的显示一些信息。或者还想运用动态脚本解决一些问题。不能用静态的方式来展示网站内容。但是这就损失了对搜索引擎的友好面。怎么样在两者之间找个中间方法呢,这就产生了伪静态技术。伪静态技术是指展示出来的是以html一类的静态页面形式,但其实是用ASP一类的动态脚本来处理的。
总结: 以.html为结尾的展现的动态页面的脚本技术.
ajax 跨域
浏览器解析ajax请求时 违反了浏览器的同源策略 这叫跨域
说明:浏览器中规定 Ajax请求 协议://域名:端口三者必须全部相同时,才能实现数据访问(同域请求),如果违反上述规则中的任意一个则该请求就是跨域访问.
如果浏览器进行跨域访问,则浏览器不予解析返回值.
跨域实现 方法一
JSONP跨域访问入门案例
利用 javaScript 中的src属性进行跨域 补充说明:通过src属性负责资源的加载.如果 需要使用数据,则需要函数回调进行调用
- 在B服务器中 有下面一组 进行特殊格式封装的数据:
3.在A服务器中 调用b服务器中的资源
<script type="text/javascript">
/*JS是解释执行的语言 */
/*定义回调函数 */
function hello(data){
alert(data.name);
}
f1({"s":"fdsad"}); // js中函数 可以通过回调 来显示数值
function f1(data){//这里的data 就等于{"s":"fdsad"}
alert(data.s);
}
</script>
<!--通过src将数据加载进来 然后通过回调函数调出数据 -->
<script type="text/javascript" src="http://manager.jt.com/test.json"></script>
JSONP介绍
艺名:json"胖"
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通
jquery 实现JSONP
需求:jsonp的方式如果采用原生的调用方式,则配置繁琐 1.javascript 2.自定义回调函数 3.特殊格式封装.
则jQuery负责封装JSONP.像常规ajax调用一样的方便.
页面封装:
a服务器 开始跨域调用
<script type="text/javascript" src="http://manager.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
alert("测试访问开始!!!!!")
$.ajax({
url:"http://manager.jt.com/web/testJSONP",
type:"get", //jsonp只能支持get请求 因为 src只能负责 接受加载资源 不能发送资源
dataType:"jsonp", //dataType表示返回值类型 表示跨域调用 跨域必须写
jsonp: "callback", //指定参数名称 get请求的name 可有可无 **默认**就是**callback**
jsonpCallback: "hello", //指定回调函数名称 可有可无
success:function (data){ //data经过jQuery封装返回就是json串
alert("==")
alert(data.id);
alert(data.name);
//转化为字符串使用
//var obj = eval("("+data+")");
//alert(obj.name);
}
});
})
</script>
b服务器接受请求
package com.jt.controller;
import com.fasterxml.jackson.databind.util.JSONPObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Jsonp {
// http://manager.jt.com/web/testJSONP?callback=jQuery111108751430559635234_1597663183849&_=1597663183850
@RequestMapping("/web/testJSONP")
public JSONPObject jsonpObject(String callback){ //JSONPObject 一个专门返回跨域的API
return new JSONPObject(callback, "{'id':'100','name':'张三'}");
}
// public String testJsonp(String callback){
// return callback+"({'id':'100','name':'abcdefg'})";
// }
}
2. cors 跨域访问
cors说明:
CORS,全称Cross-Origin Resource Sharing ,是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。
知识回顾:
JSONP: 用户利用jsonp向服务器动态获取数据的过程 主体是用户
cors : 服务器是否允许客户端访问的技术 主体是服务器
cors原理说明
用户可以像普通的ajax
请求一样发起跨域请求,/get/post/put/delete 由于当前的跨域业务比较常见,所以主流的浏览器都默认支持跨域。cors的核心我们需要配置服务器端是否允许跨域即可。
当服务器没有配置跨域访问时 发起ajax跨域 会报错
服务器实现 cors跨域
说明 : 服务器端如果需要实现CORS跨域请求,则需要在服务器端标识允许跨域的网址即可.
页面中 发起ajax跨域请求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>
<script type="text/javascript" src="http://manager.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
/*$(){}结构必然是jQuery函数类库导入后才能正确执行*/
$(function(){
alert("我执行了AJAX");
$.get("http://manager.jt.com/corsjson.json",function(data){
alert(data.name);
})
})
</script>
</head>
<body>
<h1>JSON跨域请求测试</h1>
</body>
</html>
需要被跨域访问的服务器中编辑 cors 配置信息 实现WebMvcConfigurer接口
package com.jt.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration//我是一个配置类
public class CorsConfig implements WebMvcConfigurer {
//扩展跨域请求的方法
@Override
public void addCorsMappings(CorsRegistry registry) {
//1.允许什么样的请求可以跨域
//“/web/**” web下的资源可以跨域访问
// /* 代表 只允许一级目录请求 /** 允许多级目录请求
registry.addMapping("/**")
//2.允许那些服务器可以进行访问
// .allowedOrigins("http://www.jt.com")
.allowedOrigins("*")
//是否允许携带cookie
.allowCredentials(false)
//定义探针检测时间 在规定时间内不再询问是否允许跨域
.maxAge(1800);
}
}
cors跨域响应信息
判断是否为JSONP请求方式 检查url
在 前端页面中查找代码
检查用户 jsonp跨域请求 主要关注点
关于跨域访问的全局异常处理机制
package com.jt.aop;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.vo.SysResult;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
@RestControllerAdvice //定义异常处理的通知. 只拦截Controller层抛出的异常. 并且返回值JSON串
public class SystemExceptionAOP {
/**
* 如果跨域访问发生了异常 ,则返回值结果必须经过特殊的格式封装才行.
* 如果是跨域访问形式,全局异常处理 可以正确的返回结果.
* 思路: 1.判断用户提交参数中是否有callback参数
* callback(json)
* * @param e
* @return
*/
@ExceptionHandler(RuntimeException.class)
public Object fail(Exception e, HttpServletRequest request){
//1.获取用户的请求参数
String callback = request.getParameter("callback");
//2.判断参数是否有值
if(StringUtils.isEmpty(callback)){
//用户请求不是jsonp跨域访问形式
//打印异常信息
e.printStackTrace();
return SysResult.fail();
}else{
//jsonp的报错信息.
e.printStackTrace();
return new JSONPObject(callback, SysResult.fail());
}
}
}
全局封装对象
package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 该vo对象 时系统返回值的vo对象 主要包含三个属性
* 1.设定状态吗 200表示执行成功 201 执行失败 人为定义的(和浏览器没关系)业务定义,判断对或者不对
* 2.定义返回值信息。 服务器可能会给用户一些提示的信息,例如 执行成功 用户名或者密码错误等等 域对象的交互信息
* 3.定义返回值对象 , 服务器在后端处理完成业务之后,将对象返回给前段。 数据交互
*
*/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult {
private Integer status; //200成功
private String msg;//与用户的交互信息
private Object data;//交互数据
/**
* 为了简化用户的调用过程,准备一些工具api
* 用户的关注点 1.执行成功 2.执行失败
* @param date
* @return
*/
public static SysResult fail(){
return new SysResult(201,"业务执行失败",null);
}
public static SysResult success(){//只表示成功 不携带数据
return new SysResult(200,"业务执行成功",null);
}
//bug 将STring当做相应数据 回传给客户端
//注意事项,写工具api方法时 切记 方法重载千万不要耦合
public static SysResult success(String msg,Object date){
return new SysResult(200,msg,date);
}
public static SysResult success(Object date){
return new SysResult(200,"业务执行成功",date);
}
}