前端-【学习心得】-跨域问题
我们知道,一般做web的时候会遇到所谓的跨域问题。
所谓跨域就是浏览器在全局层面禁止了页面加载或执行与自身来源不同的域的任何脚本。
比如我们本地开发的静态界面写的ajax请求如果 不进行配置是无法得到服务器响应的。
当然我们可以把静态界面放到服务器下,比如tomcat 的webapp,或者放到node express 项目的静态路径下,都可以访问成功,当然如果想要减轻服务器的负担,可以把静态文件用nginx代理。
不过不管怎么样开发起来还是多有不便,这里来跟大家分享下如何制作跨域的。
我们这里不适用jsonp,因为请求数据会被限制。
使用CORS,准备angular js作为服务端,express 作为服务端。
直接上代码,先上服务端:
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 routes = require('./web_router'); var app = express();
// view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade');
// uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(logger('dev')); app.use(bodyParser()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.all('/fruitpoint', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", '3.2.1') if (req.method == "OPTIONS") res.send(200); else next(); }); app.use('/fruitpoint', routes); // 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 handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); }
// production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); });
app.listen(3000); console.log("server start") module.exports = app;
首先展示express 的app.js ,这里给了一个路由 fruitpoint 在请求执行之前先增加跨域的设置,方法就是利用express可以截获多个请求然后放行,就在它之前再加一个。
设置响应支持跨域的代码
res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", '3.2.1') if (req.method == "OPTIONS") res.send(200); else next();
然后就是客户端的比较简单,这里我直接把app.js,controller.js和servers.js合并展示:
var main = angular.module('fruit_index', []) .config(function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers .common['X-Requested-With']; }); main.factory('MainService', function($http) { return { getMainData: function() { return $http({ method: 'post', url: 'http://localhost:3000/fruitpoint', data: { base: { reqTime: '201409041455123', proNo: '90002' }, content: { MR_ID: '1234' },
} }); } }; }); main.controller("indexcontroller",function($scope,MainService){ $scope.name="s"; MainService.getMainData().success(function(data, status, headers){ console.log(data); }); });
<!DOCTYPE html> <html ng-app="fruit_index"> <head> <meta charset="utf-8"/> <title>xxxxxx</title> <meta name="keywords" content=""/> <meta name="description" content=""/> <meta name="viewport" content="width=device-width"/> <link rel="stylesheet" href="css/reset.css"/> <link rel="stylesheet" href="css/function.css"/> <link rel="stylesheet" href="css/media.css"/> <link rel="stylesheet" href="css/animation.css"/> <link rel="stylesheet" href="css/style.css"/> <link rel="shortcut icon" href="img/favicon.ico"/> <link rel="apple-touch-icon" href="img/touchicon.png"/> <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> <script src="js/index.js"></script> <script src="lib/angular/angular.js"></script> <script src="lib/angular-animate/angular-animate.js"></script> <script src="lib/angular-sanitize/angular-sanitize.js"></script> <script src="lib/angular-ui-router/release/angular-ui-router.js"></script> <script src="lib/moment/min/moment-with-locales.js"></script> <script src="lib/angular-moment/angular-moment.js"></script> <script src="lib/angular-resource/angular-resource.js"></script> <script src="js/app.js"></script> <script src="js/services/mainservice.js"></script> <script src="js/controllers/fruitindexController.js"></script> </head> <body class="f-ff1"> <div class="m-adv1"></div> <div class="m-main"> <div class="m-maincl f-fl" ng-controller="indexcontroller"> <h1 class="title1">身边水果{{name}}</h1> </div> </div> </body> </html>
调用的静态页面东西多了点,但ng的标签还是挺简单的。