跨域解决方案与提交订单

跨域解决方案与提交订单

课程目标 

目标 1:掌握跨域请求 CORS 解决方案目标 2:完成结算页收货人地址选择功能目标 3:完成结算页支付方式选择目标 4:完成结算页商品清单功能目标 5:完成保存订单功能

1.商品详细页跨域请求 

1.1 需求分析 

从商品详细页点击“加入购物车”按钮,将当前商品加入购物车,并跳转到购物车页面。

1.2 JS 跨域请求 

这里说的 js 跨域是指通过 js 在不同的域之间进行数据传输或通信,比如用 ajax 向一个不同的域请求数据,或者通过 js 获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。

1.3 跨域调用测试 

修改 pinyougou-page-web 的 itemController.js ,引入$http 服务,修改 addToCart 方法

//添加商品到购物车

$scope.addToCart=function(){

$http.get(‘http://localhost:9107/cart/addGoodsToCartList.do?itemId=‘

+ $scope.sku.id +‘&num=‘+$scope.num).success(

function(response){

if(response.success){


location.href=‘http://localhost:9107/cart.html‘;//跳转到购


物车页面


}el

}


se{

alert(response.message);


);

}


}

测试后发现无法跨域调用

XMLHttpRequest cannot  load  http://localhost:9107/cart/addGoodsToCartList.do?itemId=112344&num=1.

No ‘Access-Control-Allow-Origin‘ header is present on the requested resource. Origin ‘http://localhost:9100‘ is therefore not allowed access. The response had HTTP status code 400.

1.4 跨域解决方案 CORS

CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)。CORS

需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器不能低于 IE10。

它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。

请求过程如下图:

Preflight Request:

然后服务器端给我们返回一个 Preflight Response

下面我们就开始动手,让我们的购物车工程能够接收跨域请求

(1)首先修改 pinyougou-cart-web 的 CartController.java 的 addGoodsToCartList 方法,添加下面两句代码

response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");

response.setHeader("Access-Control-Allow-Credentials", "true");

Access-Control-Allow-Origin

Access-Control-Allow-Origin 是 HTML5 定义的一种解决资源跨域的策略。

他是通过服务器端返回带有 Access-Control-Allow-Origin 标识的 Response header,用来解决资源的跨域权限问题。

使用方法,在 response 添加 Access-Control-Allow-Origin,例如

Access-Control-Allow-Origin:www.google.com

也可以设置为 * 表示该资源谁都可以用

(2)修改 pinyougou-item-web 的 itemController.js

//添加商品到购物车

$scope.addToCart=function(){

$http.get(‘http://localhost:9107/cart/addGoodsToCartList.do?itemId=‘   + $scope.sku.id +‘&num=‘+$scope.num,{‘withCredentials‘:true}).success(

function(response){

.......

}

);

}

调用测试,可以实现跨域了。

CORS 请求默认不发送 Cookie 和 HTTP 认证信息。如果要把 Cookie 发到服务器,一方面要服务器同意,指定 Access-Control-Allow-Credentials 字段。另一方面,开发者必须在 AJAX 请求中打开 withCredentials 属性。否则,即使服务器同意发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。

1.5 SpringMVC 跨域注解 

springMVC 的版本在 4.2 或以上版本,可以使用注解实现跨域, 我们只需要在需要跨域的方

法上添加注解@CrossOrigin 即可

@CrossOrigin(origins="http://localhost:9105",allowCredentials="true")

allowCredentials="true"  可以缺省

2.结算页-收件人地址选择 

2.1 需求与数据库分析 

2.1.1 需求描述 

在结算页实现收件人地址选择功能

2.1.2 数据库结构分析 

Tb_address 为地址表

2.2 准备工作 

2.2.1 生成代码 

使用《黑马程序员代码生成器》生成代码,并拷贝到工程

(1) AddressService 接口拷入 pinyougou-user-interface

(2) AddressServiceImpl 类拷入到 pinyougou-user-service

(3) pinyougou-cart-web 引入 pinyougou-user-interface 依赖 ,AddressController 类拷入到 pinyougou-cart-web

2.2.2 拷贝页面资源 

将 getOrderInfo.html 拷贝至 pinyougou-cart-web 的 webapp 下

2.3 实现地址列表 

2.3.1 后端代码 

(1) 修改 pinyougou-user-interface 的 AddressService.java,新增方法定义

/**

* 根据用户查询地址

@param userId

@return

*/

public List<TbAddress> findListByUserId(String userId );

(2) 修改 pinyougou-user-service 的 AddressServiceImpl.java

/**

* 根据用户查询地址

@param userId

@return    */

public List<TbAddress> findListByUserId(String userId ){

TbAddressExample example=new TbAddressExample();

Criteria criteria = example.createCriteria();


}


criteria.andUserIdEqualTo(userId);

return addressMapper.selectByExample(example);

(3) 修改 pinyougou-cart-web 的 AddressController.java

@RequestMapping("/findListByLoginUser")

public List<TbAddress> findListByLoginUser(){

String userId =

SecurityContextHolder.getContext().getAuthentication().getName();

return addressService.findListByUserId(userId);

}

2.3.2 前端代码 

(1) pinyougou-cart-web 的 cartService.js

//获取地址列表

this.findAddressList=function(){

return $http.get(‘address/findListByLoginUser.do‘);

}

(2) pinyougou-cart-web 的 cartController.js

//获取地址列表

$scope.findAddressList=function(){

cartService.findAddressList().success(

function(response){

$scope.addressList=response;

}


}


);

(3) 修改 getOrderInfo.html 引入 js

<script type="text/javascript" src="plugins/angularjs/angular.min.js">  </script>

<script type="text/javascript" src="js/base.js">  </script>

<script type="text/javascript" src="js/service/cartService.js">  </script>

<script type="text/javascript" src="js/controller/cartController.js">  </script>

指令


<


body


ng-app="pinyougou" ng-controller="


cartController" ng-init="findAddressList()">

循环列表


<

<

<

<

<

<

<

<


div


ng-repeat="address in addressList" >

class="con name">

href="javascript:;" >{{address.contact}}<span title="点击取消选择"> </a>

>

class="con address"   >{{address.address}}<span>{{address.mobile}}</span>

<span class="base" ng-if="address.isDefault==‘1‘">默认地址</span>

<span class="edittext"><a data-toggle="modal" data-target=".edit"

-keyboard="false" >编辑</a>  <a href="javascript:;">删除</a></span>

>

class="clearfix"></div>

>


div

a /div

div

data

/div


div

div /

显示效果如下:

2.4 地址选择 

(1) 在 orderInfoController.js 增加代码


//选择地址

$scope.selectAddress=function(address){

$scope.address=address;

}

//判断是否是当前选中的地址

$scope.isSelectedAddress=function(address){

if(address==$scope.address){

return true;     }else{

return false;

}

}

(2) 修改页面-点击选择


<

<

<

<

<

<


div


ng-repeat="address in addressList" >

div class="con name {{isSelectedAddress(address)?‘selected‘:‘‘}}" ><a

"javascript:;" ng-click="selectAddress(address)">{{address.contact}}<span

"点击取消选择"> </a></div>

div class="con address"   >{{address.address}}<span>{{address.mobile}}</span>

<span class="base" ng-if="address.isDefault==‘1‘">默认地址</span>

<span class="edittext"><a data-toggle="modal" data-target=".edit"

-keyboard="false" >编辑</a>  <a href="javascript:;">删除</a></span>

>

div class="clearfix"></div>

>


href= title=

data

/div


div

/

(3) 修改页面,显示选择的地址


<


div


class="fc-receiverInfo">寄送至:{{address.address}} 收货人:{{address.contact}}


{{address.mobile}}</


div


>

2.5 默认地址显示 

修改 orderInfoController.js

//查询当前登录人的地址列表

$scope.findAddressList=function(){

addressService.findListByLoginUser().success(

function(response){

$scope.addressList=response;

//设置默认地址

for(var i=0;i< $scope.addressList.length;i++){

if($scope.addressList[i].isDefault==‘1‘){


}


$scope.address=$scope.addressList[i];

break;


}


}


}


);

2.6 收件人地址增加、修改与删除 

学员实现

3.结算页-支付方式选择 

3.1 需求分析 

实现支付方式的选择,品优购支持两种支付方式:微信支付和货到付款

3.2 支付方式选择 

3.2.1 前端控制层 

cartController.js


$scope.order={paymentType:‘1‘};

//选择支付方式

$scope.selectPayType=function(type){

$scope.order.paymentType= type;

}

3.2.2 页面 

getOrderInfo.html


<

"

<


li


class="selected" ng-click="selectPayType(‘1‘)">微信付款<span title="点击取消选择

/span></li>

ng-click="selectPayType(‘2‘)">货到付款<span title="点击取消选择"></span></li>


><

li

4.结算页-商品清单与金额显示 

4.1 需求分析 

显示购物车中的商品清单以及合计数量、金额

4.2 显示商品清单 

(1) 页面 getOrderInfo.html 上初始化调用


<body ng-app="pinyougou"

ng-init="findAddressList();findCartList()">


ng-controller="cartController"

(2) 循环显示商品清单


<


div


ng-repeat="cart in cartList">

<ul class="yui3-g" ng-repeat="orderItem in cart.orderItemList">

<li class="yui3-u-1-6">

<span><img src="{{orderItem.picPath}}"/></span>

</li>

<li class="yui3-u-7-12">

<div class="desc">{{orderItem.title}}</div>

<div class="seven">7天无理由退货</div>


</li>

<li class="yui3-u-1-12">

<div class="price">¥{{orderItem.price}}</div>

</li>

<li class="yui3-u-1-12">

<div class="num">X{{orderItem.num}}</div>

</li>

<li class="yui3-u-1-12">

<div class="exit">有货</div>

</li>

</ul>


div

</ >

4.3 显示合计金额 

修改 getOrderInfo.html


<

<

<

<


div


class="list">

<span><i class="number">{{totalValue.totalNum}}</i>件商品,总商品金额</span>

<em class="allprice">¥{{totalValue.totalMoney.toFixed(2)}}</em>

>

class="fc-price">应付金额:


div

class="price">¥{{totalValue.totalMoney.toFixed(2)}}</span></ >


div

/

......


div

span

5.保存订单 

5.1 需求分析 

5.1.1 需求描述 

点击订单结算页的提交订单 ,将购物车保存到订单表和订单明细表中,并将购物车数据清除.

5.1.2 数据库结构分析 

Tb_order 为订单主表

5.2 准备工作 

5.2.1 搭建框架 

(1) 创建 pinyougou-order-interface  引入依赖 pinyougou-pojo

(2) 创建 pinyougou-order-service  (WAR) 参照其它服务工程引入依赖,添加 web.xml  spring 配置文件  dubbox 端口 20888  tomcat7 运行端口 9008

(3) pinyougou-cart-web 引入依赖 pinyougou-order-interface

5.2.2 生成代码 

生成 tb_order 表相关代码,并拷贝到工程中

5.2.3 分布式 ID 生成器 

我们采用的是开源的 twitter(  非官方中文惯称:推特.是国外的一个网站,是一个社交网络及微博客服务)  的 snowflake 算法。

(1) 将“配置文件/工具类”下的 IdWorker.java 拷贝到 common 工程

(2) 在 pinyougou-order-service 工程的 spring 配置文件中添加配置

<bean id="idWorker" class="util.IdWorker">

<!-- 进程ID -->

<constructor-arg index="0" value="0"></constructor-arg>

<!-- 数据中心ID -->

<constructor-arg index="1" value="0"></constructor-arg>

</bean>

5.3 后端代码 

5.3.1 服务实现层 

修改 pinyougou-order-service 的 OrderServiceImpl.java

@Autowired

private RedisTemplate<String, Object> redisTemplate;

@Autowired

private TbOrderItemMapper orderItemMapper;

@Autowired

private IdWorker idWorker;

/**

* 增加

*/

@Override

public void add(TbOrder order) {


//得到购物车数据

List<Cart> cartList = (List<Cart>)

redisTemplate.boundHashOps("cartList").get( order.getUserId() );

for(Cart cart:cartList){

long orderId = idWorker.nextId();

System.out.println("sellerId:"+cart.getSellerId());       TbOrder tborder=new TbOrder();//新创建订单对象

tborder.setOrderId(orderId);//订单ID

tborder.setUserId(order.getUserId());//用户名

tborder.setPaymentType(order.getPaymentType());//支付类型

tborder.setStatus("1");//状态:未付款

tborder.setCreateTime(new Date());//订单创建日期

tborder.setUpdateTime(new Date());//订单更新日期

tborder.setReceiverAreaName(order.getReceiverAreaName());//地址

tborder.setReceiverMobile(order.getReceiverMobile());//手机号

tborder.setReceiver(order.getReceiver());//收货人

tbOrder.setSourceType(order.getSourceType());//订单来源

tborder.setSellerId(cart.getSellerId());//商家ID

//循环购物车明细

double money=0;

for(TbOrderItem orderItem :cart.getOrderItemList()){

orderItem.setId(idWorker.nextId());

orderItem.setOrderId( orderId  );//订单ID


orderItem.setSellerId(cart.getSellerId());

money+=orderItem.getTotalFee().doubleValue();//金额累加

orderItemMapper.insert(orderItem);


}

tborder.setPayment(new BigDecimal(money));

orderMapper.insert(tborder);


}


}

redisTemplate.boundHashOps("cartList").delete(order.getUserId());

5.3.3 控制层 

修改 pinyougou-cart-web 的 OrderController.java

/**

* 增加

@param order

@return

*/

@RequestMapping("/add")

public Result add(@RequestBody TbOrder order){

//获取当前登录人账号

String username =

SecurityContextHolder.getContext().getAuthentication().getName();

order.setUserId(username);

order.setSourceType("2");//订单来源  PC


}


try {

orderService.add(order);

return new Result(true, "增加成功");

} catch (Exception e) {

e.printStackTrace();

return new Result(false, "增加失败");

}

5.4 前端代码 

5.4.1 服务层 

修改 pinyougou-cart-web 的 cartService.js

//保存订单

this.submitOrder=function(order){

return $http.post(‘order/add.do‘,order);

}

5.4.2 控制层 

修改 cartController.js

//保存订单

$scope.submitOrder=function(){

$scope.order.receiverAreaName=$scope.address.address;//地址

$scope.order.receiverMobile=$scope.address.mobile;//手机


function


$scope.order.receiver=$scope.address.contact;//联系人

cartService.submitOrder( $scope.order ).success(

(response){

if(response.success){

//页面跳转

if($scope.order.paymentType==‘1‘){//如果是微信支付,跳转到支付页面

location.href="pay.html";

}else{//如果货到付款,跳转到提示页面

location.href="paysuccess.html";

}

}else{

alert(response.message); //也可以跳转到提示页面

}


}


}

);

5.4.3 页面 

修改 getOrderInfo.html


<a


class="sui-btn btn-danger btn-xlarge" ng-click="submitOrder()" >提交订单</a


>

将静态原型中的 pay.html  paysuccess.html  payfail.html 拷贝到 pinyougou-cart-web 中

原文地址:https://www.cnblogs.com/chenjiaji/p/11559576.html

时间: 2024-10-28 08:44:13

跨域解决方案与提交订单的相关文章

前端常见跨域解决方案(全)

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交 2.) 资源嵌入: <link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链 3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场

前端常见跨域解决方案

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交 2.) 资源嵌入:<link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链 3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景

前端常见的跨域解决方案

什么是跨域: 一个域名下的文档或者脚本试图请求另外一个域名的下的资源 广义的跨域: 资源跳转:a链接.重定向.表单提交 资源嵌入:<link> <script>  <img>等dom标签 脚本请求:js发起的ajax请求,dom和js的跨域操作 其实就是浏览器的同源策略导限制的一类请求场景 什么是同源策略: 他是浏览器最核心的安全功能,所谓的同源策略就是:协议+域名+端口,三者相同,即便两个相同的不同的域名指向相同的ip,也非同源 同源测略限制了以下几种行为: cook

javascript跨域解决方案

最近遇到了https跨域访问http域的问题,很多朋友理所当然的认为简单,问题是https跨域访问到http域上的资源,会进行相互通信,没有解决该问题,只能把外部资源扔到了新浪的sae上,通过https访问,别跨什么协议域了,只跨主域即可! 附两篇跨域的文档 http://jiangzhenghua.iteye.com/blog/1221178 http://jiangzhenghua.iteye.com/blog/1221184 HTTPS页面包含HTTP内容时浏览器提示的绕过 http://

javascript 跨域解决方案

1 用jsonp $.getJSON(" http://www.jinanwuliangye.com/document!searchJSONResult.action?name1="+value1+"&jsoncallback=?", function(json){ if(json.属性名==值){ // 执行代码 } }); $.getJSON(" http://www.tongxinglong.com/document!searchJSONRe

跨域解决方案CORS使用方法

CORS(Cross-Origin Resource Sharing), 目前CORS还处于w3c的草案,它定义了跨域访问时服务器和客户端之间如何通信.他的原理是通过定义HTTP头部的信息,来让客户端和服务器互相确认,从而决定是否相应本次请求. 兼容性: IE10+  chrome21+  firefox21+  safari5.1+  opera12.1+ (IE8, 9中使用XDomainRequest) 详见 http://caniuse.com/cors , 可通过(new XMLHtt

js最全的十种跨域解决方案

在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义.同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法.那么什么叫相同域,什么叫不同的域呢? 同源策略 在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义.同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个

跨域解决方案二:使用JSONP实现跨域

跨域的实现方式有多种,除了 上篇文章 提到的CORS外,常见的还有JSONP.HTML5.Flash.iframe.xhr2等. 这篇文章对JSONP的跨域原理进行了探索,并将我的心得记录在这里和大家分享. JSONP跨域原理探秘 我们知道,使用 XMLHTTPRequest 对象发送HTTP请求时,会遇到 同源策略 问题,域不同请求会被浏览器拦截. 那么是否有方法能绕过 XMLHTTPRequest 对象进行HTTP跨域请求呢? 换句话说,不使用 XMLHTTPRequest 对象是否可以发送

Atitit.js跨域解决方案attilax大总结&#160;后台java&#160;php&#160;c#.net的CORS支持

Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持 1. 设置 document.domain为一致  推荐1 2. Apache 反向代理 推荐1 3. jsonp ,2 4. CORS ,2 5. iframe+post3 6. 回调解决方案>>服务端推送dwr 反向ajax3 7. 服务器中转 3 8. Js跨3 9. 从所有的浏览器都支持来看,CORS将成为未来跨域访问的标准解决方案3 10. 参考4 1. 设置 document.do