什么是跨域请求:
浏览器厂商在开发浏览器的时候设置了同源策略,
同源策略: 要求发送请求的url地址和返回响应的url地址必须保证, 协议, IP地址, 端口号不能够发生改变, 只要
这三个位置有一个发生变化, 那么浏览器就会认为这个响应不安全, 会拒绝接收响应数据, 就是跨域请求访问.
如果前端window.location.href进行跳转, 跳转到不同服务器页面, 不会触发跨域访问问题, 原因是只是页面跳转, 不会
有数据返回.
解决方案:
1. jsonp:
jquery如果发送ajax请求, 可以将数据类型设置为jsonp, 原理是jquery在发送数据的同时, 会在数据中生成
一个令牌, controller接收到数据后, 进行处理, 返回响应的时候, 将令牌原样返回, jquery会判断令牌是否
是当初自己发送的, 如果是接收响应, 如果不是, 会拒绝接收.
2. cors:
是w3c标准支持的解决方案, 原理是在响应头设置信息’Access-Control-Allow-Origin
如果使用了springMvc4.2以上版本, 可以使用@Cross注解, 就相当于设置了响应头信息.
SpringMVC跨域注解
/**
* 添加商品到购物车
* @CrossOrigin注解相当于设置了响应头信息, 是w3c支持的一种跨域解决方案
* origins属性设置的地址是, 返回响应给静态页面, 静态页面所在服务器地址,
* 也即是service_page项目地址
* @param itemId 商品库存id
* @param num 购买数量
*/
@RequestMapping("/addGoodsToCartList")
@CrossOrigin(origins="http://localhost:8086",allowCredentials="true")
购物车解析流程图:
1.界面,构成解析
2.仿京东,登录和未登录的加入购物车图解
3.集群架构
4.UI到controller的访问
购物车实现流程设计细节
购物车Controller:BuyerCarController
@RestController
@RequestMapping("/cart")
public class BuyerCarController {
@Reference
private CartService cartService;
//通过springMvc注入。
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
/**
* 添加商品到购物车
* @CrossOrigin注解相当于设置了响应头信息, 是w3c支持的一种跨域解决方案
* origins属性设置的地址是, 返回响应给静态页面, 静态页面所在服务器地址,
* 也即是service_page项目地址
* @param itemId 商品库存id
* @param num 购买数量
*/
@RequestMapping("/addGoodsToCartList")
@CrossOrigin(origins="http://localhost:8086",allowCredentials="true")
public Result addGoodsToCartList( Long itemId, Integer num){
try {
//1. 获取当前登录用户名称
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
//2. 获取购物车列表集合
List<BuyerCart> cartList = findCartList();
//3. 将当前商品加入到购物车列表集合,把得到的购物车列表直接覆盖
cartList = cartService.addItemToCartList(cartList, itemId, num);
//4. 判断当前用户是否登录, 未登录用户名为"anonymousUser"
if ("anonymousUser".equals(userName)){
//4.a.如果未登录, 则将购物车列表以键值字符串的形式,存入cookie文本中,
//其中保存时间为一个月的秒数,和设置存入字符编码为utf-8
CookieUtil.setCookie(request,response, Constants.CART_LIST_COOKIE, JSON.toJSONString(cartList),60*60*24*30,"utf-8");
}else {
//4.b.如果已登录, 则将购物车列表存入redis中
cartService.setCartListToRedis(userName,cartList);
}
return new Result(true,"添加购物车成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"添加购物车失败");
}
}
/**
* 获取购物车列表所有数据返回
* @return
*/
@RequestMapping("/findCartList")
public List<BuyerCart> findCartList(){
//1. 获取当前登录用户名称
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
//2. 从cookie中获取购物车列表json格式字符串
String cookieCartListStr = CookieUtil.getCookieValue(request, Constants.CART_LIST_COOKIE, "utf-8");
//3. 如果购物车列表json串为空,则返回"[]"格式
if (cookieCartListStr==null || "".equals(cookieCartListStr)){
cookieCartListStr="[]";
}
//4. 将购物车列表json转换为对象,购物车对象反射
List<BuyerCart> cookieCartList = JSON.parseArray(cookieCartListStr, BuyerCart.class);
//5. 判断用户是否登录, 未登录用户为"anonymousUser"
if ("anonymousUser".equals(userName)){
//5.a. 未登录, 返回cookie中的购物车列表对象,'[]'
return cookieCartList;
}else {
//5.b.1.已登录, 从redis中通过账户名,获取购物车列表对象
List<BuyerCart> redisCartListm = cartService.getCartListFromRedis(userName);
//5.b.2.判断cookie中是否存在购物车列表