美文网首页
JSONP_跨域

JSONP_跨域

作者: cctosuper | 来源:发表于2017-11-15 16:36 被阅读0次

题目1: 什么是同源策略

  • 同源策略(Same Origin Policy): 浏览器出于安全方面的考虑, 只允许与本域下的接口交互. 不同源的客户端脚本在没有明确授权的情况下, 不能读写对方的资源.
  • 本域指同域名同协议同端口,即URL完全相同
  • 注意: 对于当前页面来说页面存放的Js文件不重要, 重要的是加载该js页面所在什么域

题目2: 什么是跨域?跨域有几种实现形式

  • 跨域: 利用JS在不同域进行数据的传输或通信, 例如用ajax向一个不同的域请求数据, 或者通过JS获取页面中不同域的iframe中的数据
  • 实现形式:
    1. JSONP: 利用引入JS文件不受同源策略限制的特性, 前后端配合实现跨域访问接口
    2. CORS: W3C标准中的一个, 允许跨域发出xmlhttprequest请求, 需要服务端配合实现
    3. 降域: 修改document.domain, 将其设置为更高一级的父域, 从而符合同源策略
    4. postMessage
    5. NGINX代理
    6. node.js中间件
    7. webSocke协议跨域

题目3: JSONP 的原理是什么
JSONP就是通过script标签加载数据的方式去获取数据当做JS代码来执行; 提前在页面上声明一个函数, 函数名通过接口传参的方式传给后台, 后台解析到函数名后在原始数据上包裹这个函数名, 发送给前端
题目4: CORS是什么

  • CORS(Cross-Origin Resource Sharing) 跨域资源共享, 是一种ajax跨域请求资源的方式, 支持现代浏览器,IE10以上
  • 实现方式: 当使用XMLHTTPRequest发送请求上, 浏览器发现该请求不符合同源策略, 会给该请求加上一个请求头: Origin, 后台进行一系列处理, 如果确定接收请求则在返回结果中加一个响应头: Access-Control-Allow-Origin; 浏览器判断该响应头中是否包含Origin的值, 如果有则浏览器处理响应, 我们可以拿到响应数据, 如果不包含浏览器直接驳回, 这时我们无法拿到响应数据
  • CORS表象让人感觉他与同源ajax请求没啥区别, 代码完全一样

浏览器将CORS请求分为两类:简单请求和非简单请求
只要同时满足下面两大条件,就属于简单请求

  1. 请求方法是以下三种方法之一:
    HEAD
    GET
    POST
  2. HTTP的头信息不超出以下几种字段:
    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
    不能同时满足上面2个条件的,就属于非间请求
    比如对server端有特殊要求的请求,请求方法是PUT或者DELETE、content-type字段类型是application/json的

题目5: 根据视频里的讲解演示三种以上跨域的解决方式 ,写成博客

  1. JSONP
    通常为了减轻web服务器的负载, 我们把js, css, img等静态资源分离到另一台独立域名的服务器上,在HTML页面中再通过相应的标签从不同域名下加载静态资源, 而浏览器允许, 基于此原理, 我们可以通过动态创建script, 再请求一个带参网址实现跨域通信.

    1. 原生实现
    var script = document.creatElement('script');
    script.type = 'text/javascript';
    script.src = 'http://www.domain2.com:8080/login?            user=admin&callback=onBack';
    document.body.appendChild(script);
    function onBack(res){
      alert(JSON.stringify(res));
    }
    服务器返回
    onBack({"status":true, "user":"admin"})
    
    1. jquery ajax:
    $.ajax({
      url:'http://www.domain2.com:8080/login',
      type:'get',
      dataType:'jsonp',// 请求方式为jsonp
      jsonpCallback:"onBack",// 自定义回调函数名
      data:{}
    });
    

后端node.js代码示例:

var querystring = require('querystring');
var http = require('http');
var server = http.createServer();
server.on('request',function(req,res){
varparams = qs.parse(req.url.split('?')[1]);
var fn = params.callback;
// jsonp返回设置
res.writeHead(200,{'Content-Type':'text/javascript'});
res.write(fn+'('+JSON.stringify(params)+')');
res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');

jsonp缺点:只能实现get一种请求。
  1. 降域
    此方案仅限主域相同, 子域不同的跨域应用场景.
    实现原理: 两个页面都通过js强制设置document.domain为基础主域, 就实现了同域.
1. 父窗口: (http://www.domain.com/a.html)
document.domain = 'domain.com'
var user = 'admin'
2. 子窗口: (http://child.domain.com/b.html)
document.domain = 'domain.com'
alert('get js data from parent' + window.parent.user)
// 获取父窗口中变量
  1. location.hash + iframe跨域
    实现原理: a域与b域相互通信, 通过中间页c来实现. 三个页面, 不同域之间利用iframe的location.hash传值, 相同域之间直接js访问来通信
    具体实现: a域: a.html > b域: b.html > a域: c.html , ab不同域只能通过hash值单向通信, bc也不同域只能单向通信, 但ac同域, 所以c可通过parent.parent访问a页面所有对象
1. a.html: (http://www.domain1.com/a.html)
var iframe = document.getElementById('iframe')
setTimeout(function(){
  iframe.src = iframe.src + '#user=admin'
}, 1000); // 向b.html传hash值
functionCallback(res){
  alert('data from c.html' + res)
}// 开放给同域c.html的回调方法
2. b.html: (http://www.domain2.com/b.html)
var iframe = document.getElementById('iframe');
window.onhashchange = function(){
  iframe.src += location.hash;
}// 监听a.html传来的hash值,再传给c.html
3. c.html:(http://www.domain1.com/c.html)
window.onhashchange = function(){// 监听b.html传来的hash值
  window.parent.parent.onCallback('hello: ' + location.hash.replace('#user=',''));
}
  1. postMessage
    postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
    a.) 页面和其打开的新窗口的数据传递
    b.) 多窗口之间消息传递
    c.) 页面与嵌套的iframe消息传递
    d.) 上面三个场景的跨域数据传递
    用法:postMessage(data,origin)方法接受两个参数
    data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
    origin: 协议+主机+端口号,也可以设置为”*”,表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为”/”。
1. a.html:(http://www.domain1.com/a.html)
var iframe = document.getElementById('iframe');
iframe.onload = function(){
  var data = {name:'aym'};
   iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
}
window.addEventListener('message', function(e){
  alert('data form domain2 ' + e.data);
}, false);
2. b.html:(http://www.domain2.com/b.html)
window.addEventListener('message', function(e){
  alert('data from domain1 ' + e.data);
  var data = JSON.parse(e.data);
  if(data){
    data.number = 16;
    window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
  }
}, false);
  1. 跨域资源共享(CORS)
    普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置。
    带cookie请求:前后端都需要设置字段,另外需注意:所带cookie为跨域请求接口所在域的cookie,而非当前页。
    目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS)),CORS也已经成为主流的跨域解决方案。
1. 前端设置:
ajax:
var xhr=newXMLHttpRequest();// IE8/9需用window.XDomainRequest兼容
xhr.withCredentials=true;// 前端设置是否带cookie
xhr.open('post','http://www.domain2.com:8080/login',true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('user=admin');
xhr.onreadystatechange=function(){
  if(xhr.readyState==4&&xhr.status==200){
    alert(xhr.responseText);
  }
};
2. Nodejs后台示例:
var http=require('http');
var server=http.createServer();
var qs=require('querystring');
server.on('request',function(req,res){
  var postData='';
req.addListener('data',function(chunk){
  postData+=chunk;
});// 数据块接收中
req.addListener('end',function(){
  postData=qs.parse(postData);
// 跨域后台设置
  res.writeHead(200,{
  'Access-Control-Allow-Credentials':'true',// 后端允许发送Cookie
  'Access-Control-Allow-Origin':'http://www.domain1.com',// 允许访问的域(协议+域名+端口)
  'Set-Cookie':'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'// HttpOnly:脚本无法读取cookie
});
res.write(JSON.stringify(postData));
res.end();
});
});
server.listen('8080');
console.log('Server is running at port 8080...');

相关文章

  • JSONP_跨域

    1、同源策略 同源策略是众多的安全策略之一,是在web层面上的策略。同源策略规定:不同域的客户端脚本在没有明确授权...

  • JSONP_跨域

    题目1: 什么是同源策略 浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情...

  • JSONP_跨域

    题目1: 什么是同源策略 浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情...

  • JSONP_跨域

    1、什么是同源策略? 同源策略,即Same origin policy,它是所有支持JavaScript的浏览器都...

  • JSONP_跨域

    什么是同源策略 浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能...

  • JSONP_跨域

    1. 什么是同源策略 浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下...

  • JSONP_跨域

    1: 什么是同源策略 同源策略(Same origin policy)是一种约定,是浏览器最核心也最基本的安全功能...

  • JSONP_跨域

    1. 什么是同源策略 同源策略(Same origin Policy):浏览器出于安全方面的考虑,只允许与本域下的...

  • JSONP_跨域

    1.什么是同源策略 同源策略(Same origin Policy):浏览器出于安全方面的考虑,只允许与本域下的接...

  • JSONP_跨域

    题目1: 什么是同源策略 浏览器出于安全考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,...

网友评论

      本文标题:JSONP_跨域

      本文链接:https://www.haomeiwen.com/subject/pnrqvxtx.html