• 跨域以及解决方案


    理解跨域

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

    所谓同源就是同域名、同协议、同端口,只有同源的地址才可以相互通过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 += `<li>${e}</li>`
          })
          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 += `<li>${e}</li>`;
                    });
                    ul.innerHTML = html;
                }
            });
        }
     
    3、服务器代理
    通过服务器的文件能访问第三方资源,这个服务器文件又和当前请求的页面同源
    这个时候,当前请求的页面去访问服务器文件,就等同于直接请求第三方资源
     
    4、WebSocket协议跨域
    WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信
    同时允许跨域通讯,是server push技术的一种很好的实现
     
    前台代码
    <div>user input:<input type="text"></div>
    <script src="./socket.io.js"></script>
    <script>
    var socket = io('http://www.domain2.com:8080');
    
    // 连接成功处理
    socket.on('connect', function() {
        // 监听服务端消息
        socket.on('message', function(msg) {
            console.log('data from server: ---> ' + msg); 
        });
    
        // 监听服务端关闭
        socket.on('disconnect', function() { 
            console.log('Server socket has closed.'); 
        });
    });
    
    document.getElementsByTagName('input')[0].onblur = function() {
        socket.send(this.value);
    };
    </script>

    后台代码

    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.'); 
        });
    });
     
  • 相关阅读:
    Effective C++ 1.让自己习惯C++
    C++Primer 第十九章
    C++Primer 第十八章
    C++Primer 第十七章
    C++Primer 第十六章
    C++Primer 第十五章
    C++Primer 第十四章
    ~~在python中踩过的坑以及问题~~(不断更新)
    ~~Python解释器安装教程及环境变量配置~~
    ~~Py2&Py3~~
  • 原文地址:https://www.cnblogs.com/theblogs/p/10614131.html
Copyright © 2020-2023  润新知