Angularjs跨域

1、首先咱们要明白跨域的字面概念,读过留过印象以后,下面将会有例子进一步解释javascript

  有一篇文章《跨域的理解与实现》描述得很清楚,在这里摘录以下: 域(Domain)是Windows网络中独立运行的单位,域之间相互访问则须要创建信任关系(即Trust Relation)。信任关系是链接在域与域之间的桥梁。当一个域与其余域创建了信任关系后,2个域之间不但能够按须要相互进行管理,还能够跨网分配文件和打印机等设备资源,使不一样的域之间实现网络资源的共享与管理。html

  简单的说就是A网站的javascript代码试图访问B网站,包括提交内容和获取内容,但因为安全缘由,跨域访问是被各大浏览器所默认禁止的。前端

  但怎么样才算跨域呢?这里举了几个例子(什么是跨域,什么是不算跨域)java

  http://www.a.com/a.js与http://www.a.com/b.js同一域名下容许angularjs

  http://www.a.com/lab/a.js与http://www.a.com/script/b.js同一域名下不一样文件夹容许ajax

  http://www.a.com:8000/a.js与http://www.a.com/b.js同一域名,不一样端口不容许json

  http://www.a.com/a.js与https://www.a.com/b.js同一域名,不一样协议不容许后端

  http://www.a.com/a.js与http://70.32.92.74/b.js域名和域名对应ip不容许跨域

  http://www.a.com/a.js与http://script.a.com/b.js主域相同,子域不一样不容许浏览器

  http://www.a.com/a.js与http://a.com/b.js同一域名,不一样二级域名(同上)不容许(cookie这种状况下也不容许访问)

  http://www.cnblogs.com/a.js与http://www.a.com/b.js不一样域名不容许

2、明白了跨域是什么以后,下面一一举出解决跨域的各类办法。

  总的来讲共有2种方法,

  1.jsonp方式(其中jsonp方式能够用原生js,ajax,angular.js均可以实现)

    实现以前,先理解下jsonp是什么?

    为了便于客户端使用数据,逐渐造成了一种非正式传输协议,人们把它称做JSONP,该协议的一个要点就是容许用户传递一个callback参数给服务端,而后服务端返回数据时会将这个callback参数做为函数名来包裹住JSON数据,这样客户端就能够随意定制本身的函数来自动处理返回数据了。具体理解看代码:

<script>
    function getData(){
        var script = document.createElement('script');
        script.type = 'text/javascript';
//        同源策略不阻止将动态脚本元素插入文档中因此脚本元素是能够跨域访问的,因此这里用到原生js,其中callbackFunc实际上是个方法,因此咱们写回调方法名字要跟这个一致
        var myUrl = 'http://c.m.163.com/nc/article/headline/T1348647853363/0-10.html';
        script.src = 'http://localhost:8000/?myUrl=' + myUrl + '&callback=callbackFunc';
        document.getElementsByTagName('head')[0].appendChild(script);
    }
    function callbackFunc(data){
        console.log(data);
    }
</script>

  下面看服务端的配合,上面代码中说了callback后跟的是一个函数是和后台约定好的函数,那么后台须要把jsonp数据包裹在整个函数里,而后返回处理后的数据,这样就完成了前端和后台的jsonp协议,实现了跨域请求

  上面代码中有提到同源策略,这里补充一下。同源策略就是阻止从一个域上加载的脚本获取或操做另外一个域上的文档属性(不阻止将动态脚本元素插入文档中因此脚本元素是能够跨域访问的)。

var http = require('http');
var url = require('url');
var qs = require('querystring');
http.createServer(function(req,res){
    //建立一个结果对象,用来装载数据
    var resultData = '';
    //取出网址后面的参数
    var query = url.parse(req.url).query;
    console.log(query);
    //先将字符串转化为对象
    var qs_parse = qs.parse(query);
    console.log(qs_parse);
    //再将muUrl参数当作路径发送请求
    http.get(qs_parse.myUrl,function(request){
        request.setEncoding('utf-8');
        request.on('data',function(result){
            resultData += result;
        });
        request.on('end',function(){
            console.log(resultData);
            var str = qs_parse.callback + '(' + JSON.stringify(resultData) + ')';
            res.end(str);
        });
    }).on('error',function(error){
        console.log(error);
});
}).listen(8000);
console.log('server is running at 8000');

  看ajax实现代码(服务器代码同上):

<script>
    function getData(){
        var myUrl = 'http://c.m.163.com/nc/article/headline/T1348647853363/0-10.html';
        var url = 'http://localhost:8000/?myUrl=' + myUrl;
        //ajax会给咱们生成那个callback
        $.ajax({
            /***
             * 请求路径
             * 请求方法
             * 传输协议
             * 成功、失败回调函数
             */
            url:url,
            type:'get',
            dataType:'jsonp',
            success:function(result){
                console.log(JSON.parse(result));
            },
            error:function(e){
                console.log(e);
            }
        });
    }
</script>

  看angular.js实现方法(服务器同上代码同上):

angular.module('myApp',[])
    .controller('myController',['$scope','$http',function($scope,$http){
        $scope.getData = function(){
            var myUrl = 'http://c.m.163.com/nc/article/headline/T1348647853363/0-10.html';
            $http({
                method:'jsonp',
                url:'http://localhost:8000/?myUrl=' + myUrl + '&callback=JSON_CALLBACK'
                //这里的callback是angular自动生成的,JSON_CALLBACK表明着自动生成的回调函数名
            }).then( function success(result){
                console.log(result);
            },function error(e){
                console.log(e);
            });
        }
    }]);

  

  2.post设置请求头的方式,angularjs内置封装了类ajax的网络服务$http,从而实现了不依赖外部插件来完成完整的先后端分离方案。

angular.module('myApp',[]).controller('myController',['$scope','$http',function($scope,$http){
    $scope.getData = function(){
        $http({
            method:'POST',
            headers:{
                //在请求的时候设置请求头,固然请求有不少种,咱们以这种为例
            'content-type':'application/x-www-form-urlencoded'
            },
            url:'http://localhost:8000',
            data:{
                //字符串或者对象,这个对象包含了请求体的全部内容,会被发送给服务器
                myUrl:'http://c.m.163.com/nc/article/headline/T1348647853363/0-10.html'
            }
        }).then(function success(result){
            console.log(result);
        },function error(error){
            console.log(error);
        });
    }
}]);

  

由于是post请求方式,服务器端代码也须要改动:(设置为*表明任意,这样前端和后台配合就完成了post请求的跨域操做、)

 

var http = require('http');
var url = require('url');
http.createServer(function(req,res){
    //设置编码格式
    req.setEncoding('utf-8');
    //设置响应头,表示任意匹配,
    res.setHeader('Access-Control-Allow-Origin','*');
    var postData = '';
    req.addListener('data',function(chunk){
        postData += chunk;
    });
    req.on('end',function(){
        console.log('接受成功');
        var myUrl = JSON.parse(postData).myUrl;
        console.log(myUrl);
        var result = '';
        http.get(myUrl,function(request){
            request.setEncoding('utf-8');
            request.on('data',function(chunk){
                result += chunk;
            });
            request.on('end',function(){
                res.end(result);
            })
        }).on('error',function(error){
            console.log(error);
        });
    });
}).listen(8000);
相关文章
相关标签/搜索