转自:https://www.cnblogs.com/best/tag/Angular/
服务从
代码直接与
服务器进行交互,底层是通过
实现,与
中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) { });详细的配置如下:
这里使用NodeJS+Express作为后台服务,完成一个简单的汽车管理功能:
cars.js
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;
app.js
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();//指定视图引擎为ejsapp.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 handlerapp.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err);});// error handlerapp.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;
www
#!/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);}
示例代码:
服务
运行结果:
问题:如果后台服务不是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 序列化参数,这个服务需要单独依赖。
示例:
结果: