20.发送http请求服务 ($http)_json20.发送http请求服务 ($http)_ico_0220.发送http请求服务 ($http)_ico_0220.发送http请求服务 ($http)_web服务器_04服务从20.发送http请求服务 ($http)_json_0520.发送http请求服务 ($http)_json_0620.发送http请求服务 ($http)_json_0720.发送http请求服务 ($http)_异步请求_0820.发送http请求服务 ($http)_ico_0920.发送http请求服务 ($http)_异步请求_1020.发送http请求服务 ($http)_web服务器_1120.发送http请求服务 ($http)_json_1220.发送http请求服务 ($http)_web服务器_13代码直接与20.发送http请求服务 ($http)_web服务器_1420.发送http请求服务 ($http)_html_1520.发送http请求服务 ($http)_异步请求_16服务器进行交互,底层是通过20.发送http请求服务 ($http)_json_0520.发送http请求服务 ($http)_json_1220.发送http请求服务 ($http)_json_0520.发送http请求服务 ($http)_json_20实现,与20.发送http请求服务 ($http)_异步请求_2120.发送http请求服务 ($http)_json_2220.发送http请求服务 ($http)_异步请求_0820.发送http请求服务 ($http)_html_1520.发送http请求服务 ($http)_web服务器_1120.发送http请求服务 ($http)_ico_26中http服务从AngularJS代码直接与Web服务器进行交互,底层是通过AJAX实现,与jQuery中.ajax类似

 

通过$http封装后的方法:

delete(url,[config]) 发送谓词为delete的异步请求

get(url,[config]) 发送谓词为get的异步请求

head(url,[config])  发送谓词为head的异步请求

jsonp(url,[config]) 发送通过jsonp实现跨域的同步请求的请求

post(url,data,[config]) 发送谓词为post的异步请求

put(url,data[config]) 发送谓词为put的异步请求

基本用法:

$http({method: 'GET', url: '/someUrl'}).

success(function(data, status, headers, config) {

}).

error(function(data, status, headers, config) {

});

详细的配置如下:

20.发送http请求服务 ($http)_ico_27

20.发送http请求服务 ($http)_异步请求_28

这里使用NodeJS+Express作为后台服务,完成一个简单的汽车管理功能:

cars.js



20.发送http请求服务 ($http)_异步请求_29

var express = require('express');
var router = express.Router();
var _= require('lodash');

var cars=[];
cars.push({id:201701,name:"BMW",price:190,speed:"210km/h",color:"白色"});
cars.push({id:201702,name:"BYD",price:25,speed:"160km/h",color:"红色"});
cars.push({id:201703,name:"Benz",price:300,speed:"215km/h",color:"蓝色"});
cars.push({id:201704,name:"Honda",price:190,speed:"170km/h",color:"黑色"});
cars.push({id:201705,name:"QQ",price:130,speed:"210km/h",color:"白色"});

/* Get */
/*获得所有汽车*/
/*url /cars/*/
router.get('/', function(req, res, next) {
res.json(cars);
});

/*Get*/
/*获得汽车通过id*/
/*url:/cars/:id */
router.get('/:id', function(req, res, next) {
//从路径中映射参数,转换成数字
var id=parseInt(req.params.id);
var car=_.find(cars,{id:id});
res.json(car);
});

/*Post*/
/*添加汽车*/
/*url:/cars/car */
router.post('/car', function(req, res, next) {
console.log("收到请求");
var car=req.body; //从请求正文中获得json对象
car.id=_.last(cars).id+1; //将编号修改为最后一辆车的编号+1
cars.push(car); //将汽车对象添加到集合中
res.json(car); //将添加成功的车以json的形式返回
});

/*Put*/
/*修改汽车*/
/*url:/cars/car */
router.put('/car', function(req, res, next) {
var car=req.body; //从请求正文中获得json对象
console.log(req.body);
var index=_.findIndex(cars,{id:parseInt(car.id)}); //根据id获得车在集合中的下标

cars[index]=car; //替换原对象
//res.json(car); //将修改后的车以json的形式返回
res.send({status:"success", message:"更新成功!"});
});

/*Delete*/
/*删除汽车*/
/*url:/cars/:id */
router.delete('/id/:id', function(req, res, next) {
//获得url中的编号参数
var id=parseInt(req.params.id);
var index=_.findIndex(cars,{id:id}); //根据id获得车在集合中的下标
cars.splice(index,1); //在cars数组中删除下标从index开始的1条数据
res.json(cars);
});

module.exports = router;


20.发送http请求服务 ($http)_异步请求_29


app.js



20.发送http请求服务 ($http)_异步请求_29

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');
var pdts = require('./routes/product');
var task = require('./routes/task');
var cars = require('./routes/cars');

var app = express();

//指定视图引擎为ejs
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "content-type");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});

app.use('/', index);
app.use('/users', users);
app.use('/pdt', pdts);
app.use("/task",task);
app.use("/cars",cars);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

module.exports = app;


20.发送http请求服务 ($http)_异步请求_29


www



20.发送http请求服务 ($http)_异步请求_29

#!/usr/bin/env node

/**
* 依赖模块,导入
*/

var app = require('../app');
var debug = require('debug')('nodejsexpress:server');
var http = require('http');

/**
* 从上下文环境中获得监听端口,如果空则3000
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* 创建Web服务器
*/

var server = http.createServer(app);

/**
* 开始监听
*/

server.listen(port);
server.on('error', onError); //指定发生错误时的事件
server.on('listening', onListening); //当监听成功时的回调

/**
* 规范化端口
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
*错误事件监听
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

//错误处理
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1); //结束程序
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* 当用户访问服务器成功时的回调
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}


20.发送http请求服务 ($http)_异步请求_29


示例代码:



20.发送http请求服务 ($http)_异步请求_29

<!DOCTYPE html>
<!--指定angular管理的范围-->
<html ng-app="carApp">

<head>
<meta charset="UTF-8">
<title>服务</title>
<style>
* {
margin: 0;
padding: 0;
font-family: microsoft yahei;
font-size: 14px;
}

body {
padding-top: 20px;
}

.main {
width: 90%;
margin: 0 auto;
border: 1px solid #777;
padding: 20px;
}

.main .title {
font-size: 20px;
font-weight: normal;
border-bottom: 1px solid #ccc;
margin-bottom: 15px;
padding-bottom: 5px;
color: blue;
}

.main .title span {
display: inline-block;
font-size: 20px;
background: blue;
color: #fff;
padding: 0 8px;
background: blue;
}

a {
color: blue;
text-decoration: none;
}

a:hover {
color: orangered;
}

.tab td,
.tab,
.tab th {
border: 1px solid #777;
border-collapse: collapse;
}

.tab td,
.tab th {
line-height: 26px;
height: 26px;
padding-left: 5px;
}

.abtn {
display: inline-block;
height: 20px;
line-height: 20px;
background: blue;
color: #fff;
padding: 0 5px;
}

.btn {
height: 20px;
line-height: 20px;
background: blue;
color: #fff;
padding: 0 8px;
border: 0;
}

.abtn:hover,
.btn:hover {
background: orangered;
color: #fff;
}

p {
padding: 5px 0;
}

fieldset {
margin-top: 10px;
border: 1px solid #ccc;
padding: 5px 10px;
}

fieldset legend {
margin-left: 10px;
font-size: 16px;
}
</style>
</head>

<body>
<!--指定控制器的作用范围-->
<form ng-controller="CarController" class="main">
<h2 class="title"><span>汽车管理</span></h2>
<table border="1" width="100%" class="tab">
<tr>
<th>序列</th>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>颜色</th>
<th>速度</th>
<th>操作</th>
</tr>
<tr ng-repeat="c in cars">
<td>{{$index+1}}</td>
<td>{{c.id}}</td>
<td>{{c.name}}</td>
<td>{{c.price}}</td>
<td>{{c.color}}</td>
<td>{{c.speed}}</td>
<td>
<a href="#" ng-click="del(c.id)">删除</a>
<a href="#" ng-click="edit(c)">编辑</a>
</td>
</tr>
</table>
<fieldset>
<legend>汽车详细</legend>
<p>
<label for="id">编号</label>
<input ng-model="car.id" id="id" ng-readonly="true" />
</p>
<p>
<label for="name">名称</label>
<input ng-model="car.name" id="name" />
</p>
<p>
<label for="price">价格</label>
<input ng-model="car.price" id="price" />
</p>
<p>
<label for="color">颜色</label>
<input ng-model="car.color" id="color" />
</p>
<p>
<label for="color">速度</label>
<input ng-model="car.speed" id="speed" />
</p>
<button ng-click="save()" class="btn">保存</button>
<button ng-click="clear()" class="btn">清空</button>
</fieldset>
</form>

<!--引入angularjs框架-->
<script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//定义模块,指定依赖项为空
var carApp = angular.module("carApp", []);

//定义控制器,指定控制器的名称,$scope是全局对象
carApp.controller("CarController", ['$scope', '$http', function($scope, $http) {
$scope.cars = [];
$scope.save = function() {
$http({
url:"http://127.0.0.1:3000/cars/car",
data:$scope.car,
method: $scope.car.id?"PUT":"POST"
})
.success(function(data, status, headers, config) {
if($scope.car.id){
alert("修改成功");
}else{
$scope.cars.push(data);
}
})
.error(function(data, status, headers, config) {
alert(status);
});
}

$scope.edit=function(c){
$scope.car=c;
}
$scope.clear=function(){
$scope.car={};
}

$http.get("http://127.0.0.1:3000/cars")
.success(function(data, status, headers, config) {
$scope.cars = data;
})
.error(function(data, status, headers, config) {
alert(status);
});

$scope.del = function(id) {
$http.delete("http://127.0.0.1:3000/cars/id/" + id)
.success(function(data, status, headers, config) {
$scope.cars = data;
})
.error(function(data, status, headers, config) {
alert(status);
});
}
}]);
</script>
</body>

</html>


20.发送http请求服务 ($http)_异步请求_29


运行结果:

20.发送http请求服务 ($http)_web服务器_37

问题:如果后台服务不是Restful,不接收application/json的参数,则需要修改。Angular的post和put请求Content-Type: application/json默认情况下,jQuery传输数据使用Content-Type: x-www-form-urlencodedand和类似于"foo=bar&baz=moe"的序列,然而AngularJS,传输数据使用Content-Type: application/json和{ "foo": "bar", "baz": "moe" }这样的json序列。请求时修改请求头部内容:

headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }

$httpParamSerializerJQLike 序列化参数,这个服务需要单独依赖。

示例:

20.发送http请求服务 ($http)_ico_38

20.发送http请求服务 ($http)_html_39

结果:

20.发送http请求服务 ($http)_ico_40