跨域以及解决方案

理解跨域

不同源地址之间的请求称之为跨域请求(跨源)

所谓同源就是同域名、同协议、同端口,只有同源的地址才可以相互通过ajax方式请求

 btn.onclick = function(){
    let xhr = new XMLHttpRequest;
    // xhr.open('get','http://localhost:2019');//非跨域
    xhr.open('get','http://www.baidu.com');//跨域
    xhr.onload = function(){
        document.write(xhr.responseText)
    }
    xhr.send();
   }

控制台出现 Access-Control-Allow-Origin,就说明已经跨域了

 

是什么导致了跨域的产生,就会说到浏览器的一种安全机制 —— 同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响

同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性

同源策略限制以下几种行为:

1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送

 

 

解决跨域的方案:

1、CORS

CORS是一个W3C标准,全称是"跨域资源共享"
浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉
因此实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信
高版本的XMLHttpRequest + 服务器权限解决跨域问题
 
  // 处理成功失败返回格式的工具
    const {successBody} = require('../utli')
    class CrossDomain {
      static async cors (ctx) {
        const query = ctx.request.query
        // *时cookie不会在http请求中带上
        ctx.set('Access-Control-Allow-Origin', '*')
        ctx.cookies.set('tokenId', '2')
        ctx.body = successBody({msg: query.msg}, 'success')
      }
    }
    module.exports = CrossDomain

前台只需要正常发送请求

   fetch(`http://localhost:9871/api/cors?msg=helloCors`).then(res => {
      console.log(res)
    })

 

 
2、JSONP(json+padding)
script标签中的src能够直接跨域访问资源,并且尽量解析js代码
jsonp必须具备以下条件:
1)保证全局有个函数
2)数据必须是这个函数的调用格式
3)当要请求数据时候,创建一个script标签,把scr等于请求的接口,再把script标签插入到页面,这个时候就做到了按需请求
 
 function fn(data){
      let html = '';
      data.s.forEach(e=>{
        html += `
  • ${e}
  • ` }) box.innerHTML = html; console.log(data) } txt.onkeyup = function(){ let jk = document.createElement('script'); jk.src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+this.value+'&cb=fn' document.getElementsByTagName('head')[0].appendChild(jk); }

     

    jquery的jsonp

       txt.onkeyup = function(){
            $.ajax({
                url:'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?cb=?',
                data:{
                    wd:$(this).val()
                },
                dataType:'jsonp',
                success(data){
                    let html = '';
                    data.s.forEach(e=>{
                        html += `
  • ${e}
  • `; }); ul.innerHTML = html; } }); }

     

     
    3、服务器代理
    通过服务器的文件能访问第三方资源,这个服务器文件又和当前请求的页面同源
    这个时候,当前请求的页面去访问服务器文件,就等同于直接请求第三方资源
     
    4、WebSocket协议跨域
    WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信
    同时允许跨域通讯,是server push技术的一种很好的实现
     
    前台代码
    user input:

     

    后台代码

    var http = require('http');
    var socket = require('socket.io');
    
    // 启http服务
    var server = http.createServer(function(req, res) {
        res.writeHead(200, {
            'Content-type': 'text/html'
        });
        res.end();
    });
    
    server.listen('8080');
    console.log('Server is running at port 8080...');
    
    // 监听socket连接
    socket.listen(server).on('connection', function(client) {
        // 接收信息
        client.on('message', function(msg) {
            client.send('hello:' + msg);
            console.log('data from client: ---> ' + msg);
        });
    
        // 断开处理
        client.on('disconnect', function() {
            console.log('Client socket has closed.'); 
        });
    });

     

     

    转载于:https://www.cnblogs.com/theblogs/p/10614131.html

    你可能感兴趣的:(跨域以及解决方案)