跨域及实现的几种方式

一、 跨域的概念

  • 同源策略(Same origin Policy):
    同源策略是指浏览器处于安全考虑,只允许与本域下的接口进行交互,不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。

  • 同源(本域)的概念:
    同协议:都是为http或者https;
    同域名:http://a.com/index.html 与 http://a.com/server.js 域名一致;
    同端口:端口号一致(如都为8080)。

  • 跨域就是因为浏览器的同源策略机制存在而产生的,跨域的几种形式:

  1. http://www.abc.com/index.html 调用 http://www.abc.com/server.php
    (同源,非跨域,协议、域名及端口号都一致)
  2. http://www.abc.com/index.html 调用 http://www.def.com/server.php
    (主域名不同,跨域)
  3. http://abc.a.com/index.html 调用 http://def.a.com/server.php
    (子域名不同:abc/def,跨域)
  4. http://www.abc.com:8080/index.html 调用 http://www.abc.com:8081/server.php
    (端口不同,跨域)
  5. http://www.abc.com/index.html 调用 https://www.abc.com/server.php
    (协议不同:http/https,跨域)

需要注意的是:对于当前页面来说页面存放的 JS 文件的域不重要,重要的是加载该 JS 页面所在什么域。

二、跨域的四种实现形式

1. JSONP
  • JSONP(JSON with padding)原理:
    利用html里面script标签可以加载其他域下的js这一特性,使用script src的形式来获取其他域下的数据,但是因为是通过标签引入的,所以会将请求到的JSON格式的数据作为js去运行处理,显然这样运行是不行的,所以就需要提前将返回的数据包装一下,封装成函数进行运行处理,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。(JSONP 需要对应接口的后端的配合才能实现)

  • 实例:



当script src请求到达后端后,后端会去解析callback这个参数获取到字符串showData,在发送数据后端返回数据用showData封装一下,即 showData({"json数据"}) ,前端script标签在加载数据后会把json数据作为showData的参数,调用函数运行。

2. CORS
  • CORS 的概念:
    CORS全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。

  • 实现方式:
    当使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。

  • 实例:

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('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)

index.html




  
    3. 降域(前提主域名要一致)

    http://a.yilia.com 调用http://b.yilia.com

    
    //将两个域名都降域,此时就可以相互访问了
    
    4. postMessage

    假设有两个域名(主域域名不一致),其中iframe页面是允许访问调用,那么就可以用postMessage实现。
    原理:
    a域名发送请求postMessage,b域名间听到了message事件,就处理并返回数据

    //b域名
    
    

    你可能感兴趣的:(跨域及实现的几种方式)