JSONP,跨域

JSONP、跨域是面试必问问题之一
困难在于脑海里认为一个ajax请求的结果是一个json或XML
如果不用ajax请求

json内容不是固定的,传什么给什么

}else if(path === '/main.js'){  
    var string = fs.readFileSync('./main.js', 'utf8')
    response.setHeader('Content-Type', 'application/javascript')
    response.end(string.replace('%xxx%', query.content))
  }else{

jsonp = json+padding
发一个请求,服务器根据请求参数返回js,js插入页面,被执行

如果js所在的源与要请求的源不一样,浏览器会拒绝把响应给js

CORS

只要JS请求的源在响应里加上
:

状态码
2xx 一切安好
3xx 滚 301:滚到另外一个地址上去 302:
4xx 你错了
5xx 我错了
200 ok
204 新建成功

403:没有权限访问
404:没有找到

 btn.onclick = function(){
    var number = parseInt(Math.random() * 10000000,10)
    var functionName = 'jQuery'+ number

    window[functionName] = function(data){
      console.log(data)
    }

    var script = document.createElement('script')
    var value = document.querySelector('#xxx').value
    script.src = '/main.js?content=' + functionName 
    document.body.appendChild(script)
  }
 btn.onclick = function(){
    jsonp('/main.js', 'content')
  }

  function jsonp(url, param){
    var number = parseInt(Math.random() * 10000000,10)
    var functionName = 'jQuery'+ number

    window[functionName] = function(data){
      console.log(data)
    }

    var script = document.createElement('script')
    var value = document.querySelector('#xxx').value
    script.src = url + '?'+ param + '=' + functionName 
    document.body.appendChild(script)
  }

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

题目2: 什么是跨域?跨域有几种实现形式。
1.JSONP
例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。

function getData(data){
    //这里是对获取的数据的相关操作
    console.log(data);
    //数据获取到后移除创建的script标签
    document.body.removeChild(originData);
}
var originData = document.createElement('script');
originData.src = 'http://www.jesse.com/data.js';
originData.setAttribute("type", "text/javascript");
document.body.appendChild(originData);

2.CORS
跨源资源共享(CORS)定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS允许一个域上的网络应用向另一个域提交跨域AJAX请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。它只要JS请求的源在响应里加上Access-Control-Allow-Origin:

3.降域
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。 具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上 document.domain = "a.com";然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以 “交互”了。

4.postMessage
window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

JSONP是针对接口的,CORS是针对域名的有可能会遭到XSS攻击,CORS在IE8上的兼容性不好,偶尔调用的话就可以选JSONP

题目3: JSONP 的原理是什么?
1.页面上调用js文件时不受跨域的影响,而且,凡是拥有src属性的标签都拥有跨域的能力,比如

router.js

app.get('/getNews', function(req, res){
    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }
    var cb = req.query.callback;
    if(cb){
        res.send(cb + '('+ JSON.stringify(data) + ')');
    }else{
        res.send(data);
    }
    
})

CORS
index.html




  


  
  • 第11日前瞻:中国冲击4金 博尔特再战
  • 男双力争会师决赛
  • 女排将死磕巴西!

router.js

app.get('/getNews', function(req, res){
    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }
    
    res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
    res.send(data);
})

postMessage
a.html



  
    
    


    

postMessage

b.html



  
    
    


    
    
    


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