跨域

1、什么是同源策略?

       同源策略是指浏览器出于安全方面的考虑,只允许页面与本页面相同域下的接口进行数据交互,不同源的数据或脚本在没有明确授权的情况下,不能读写对方资源。

同源要求:同域名、同端口、同协议,三者缺一不可。

2、什么是跨域?列举跨域有几种实现形式

        跨域指的是跨过同源策略,实现不同域之间进行数据交互的过程叫跨域。跨域的实现形式主要有JSONP方法、CORS方法、降域和postMessage等。

a、JSONP:依托在html下script可以加载任意域下数据这一特点,将script的src属性设置成欲请求的数据地址,先通过script去加载对应数据并将其作为js在当前页面运行,就实现了跨域操作。然而,对于某些json格式数据直接作为js执行时根本无法将这些数据进行完美解析渲染,所以可以通过在请求url末尾加上一个回调函数,并和后端进行约定好返回数据的格式,将返回的数据(如json数据)构造成能作为js直接执行的格式,就实现了跨域同时前后端良好的交互。如下面例子:

```

var http = require('http')

var fs = require('fs')

var path = require('path')

var url = require('url')

http.createServer(function(req, res){

  var pathObj = url.parse(req.url, true)

  switch (pathObj.pathname) {

    case '/getNews':

      var news = [

        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",

        "正直播柴飚/洪炜出战 男双力争会师决赛",

        "女排将死磕巴西!郎平安排男陪练模仿对方核心"

        ]

      res.setHeader('Content-Type','text/json; charset=utf-8')

      if(pathObj.query.callback){

        res.end(pathObj.query.callback + '(' + JSON.stringify(news) + ')')

      }else{

        res.end(JSON.stringify(news))

      }

      break;

    default:

      fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){

        if(e){

          res.writeHead(404, 'not found')

          res.end('

404 Not Found

')

        }else{

          res.end(data)

        }

      })

  }

}).listen(8080)

```

后端与前端约定,当请求url的query.callback存在时,就将原来的json数据包装成callback + 原json数据的格式发送给浏览器;而前端则通过如下代码来实现数据请求和解析渲染:

```

 

   

       

   

 

```

约定的callback为appendHtml,在js中定义好appendHtml函数,将后端返回的包装好的appendHtml({json数据})直接作为函数执行,拼装DOM后渲染到页面上,实现跨域请求数据,并通过js操作该数据展现在当前页面上。

b、CORS方法

CORS(Cross Origin Resourse Sharing),即跨域资源共享,当使用ajax跨域请求数据时,浏览器会给违反同源策略的域加上请求头origin,此时如果不做任何处理,浏览器会拒接接受该请求返回的数据使得数据交互失败,为了跨域实现ajax请求数据,需要在服务器的返回结果中加上:Access-Control-Allow-Origin:(发请求的域名)来提醒浏览器本数据允许该域请求,从而克服同源策略,获取到数据。例如下面例子:

index.html

```

   

   

   

    Document

       

               

                   

               

             

           

```

server.js

```

var http = require('http')

var fs = require('fs')

var path = require('path')

var url = require('url')

http.createServer(function(req, res){

  var pathObj = url.parse(req.url, true)

  switch (pathObj.pathname) {

    case '/getNews':

      var news = [

        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",

        "正直播柴飚/洪炜出战 男双力争会师决赛",

        "女排将死磕巴西!郎平安排男陪练模仿对方核心"

        ]

      res.setHeader('Content-Type','Text/plain; charset = utf-8')

      res.setHeader('Access-Control-Allow-Origin','http://localhost:8080')

      //res.setHeader('Access-Control-Allow-Origin','*')

      res.end(JSON.stringify(news))

      break;

    default:

      fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){

        if(e){

          res.writeHead(404, 'not found')

          res.end('

404 Not Found

')

        }else{

          res.end(data)

        }

      })

  }

}).listen(8080)

```

在本地启动服务器,通过浏览器访问localhost:8080/index.html点击button按钮去跨域请求http://127.0.0.1:8080域下getNews数据,正常情况下,浏览器会在同源策略限制下无法请求到数据,这里我们在服务器返回的数据响应头中加上Access-Control-Allow-Origin:http://localhost:8080,将http://localhost:8080设置允许获取getNews,即可跨域请求到该数据。

c、降域

对于后缀相同的两个不同域之间(如:同一个页面上两个iframe   a.jrg.com和b.jrg.com),正常情况下两个iframe之间不能数据交互,但如果在对页面的两个iframe进行降域(document.domain = "jrg.com"),则可在两个frame之间进行数据交互,即通过降域实现跨域。  

你可能感兴趣的:(跨域)