同源策略:协议、端口号、主机都一致允许交互,这是浏览器的安全机制。

一、jsonp跨域

        JSONP 是一个非官方的跨域解决方案,缺点: 只支持 get ,不支持 post 。

        原理:借助了script标签中的src不受限于同源策略。

        客户端和服务器端常用的数据格式就是 JSON 格式了,我们可以把数据的格式设置成 json 格式,由 于我们利用 script (src属性)获取数据, script 会被执行,所以服务器给真实数据外包一个函数, 在外包一层作为传输用的 JSON 格式的数据。客户端收到之后就行调用函数获取数据。

        语法,jsonp 包含三部分: jsonp ( url , data (参数), options (回调函数,可以搭配 promise 来使用))【也可以用jq实现(略)】

//前端发送请求,给发送请求的代码绑定的事件函数:

// 绑定事件 鼠标失去焦点
input.onblur = function () {
    // 获取用户的输入值
    let username = this.value
    // 向服务器端发送请求 检测用户是否存在
    // 1. 创建script标签
    const script = document.createElement('script')
    // 2. 设置标签的src属性
    script.src = 'http://127.0.0.1:8000/checkusername'
    // 3. 将script插入到文档中 不插入到文档中浏览器是不会发送请求的
    document.body.appendChild(script)
}


//后端具体操作nodejs的server.js中

// checkusername
app.all("/checkusername", (request, response) => {
    // response.send("hello jsonp server"); //这样返回的话浏览器解析不了
    // response.send("console.log('hello jsonp-server')"); //返回的应该是一段js代码 是一个函数的调用
    // 标准的样式
    const data = {
        exist: 1,
        message: "用户名已经存在",
    };
    // 将数据转换成字符串
    let str = JSON.stringify(data);
    // 返回结果
    response.end(`handle(${str})`); //返回的响应体
    handle({"name":"
});

二、跨域资源共享(CORS)

        CORS ( Cross-Origin Resource Sharing ),跨域资源共享。 CORS 是官方的跨域解决方案,它的 特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。

过程有点像TCP三次握手:

        浏览器必须首先使用 OPTIONS 方法发起一个预检请 求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证 相关数据)。

三、WebSocket协议跨域

WebSocket协议是HTML5的新协议。能够实现浏览器与服务器全双工通信,同时允许跨域,是服务端推送技术的一种很好的实现。webSocket本身不存在跨域问题,所以我们可以利用webSocket来进行非同源之间的通信。

http协议下,服务器不会主动向客户端发起请求,只会响应。

在这种状态下,如果要网页主动刷新反馈,如页游这种,会一直更新数据的情况,一种常见方案是定时向服务器发请求来刷新,用户层面没感知,但其实一直发请求实际是由带宽占用的;

方案二,长轮询,客户端发起请求后超时时间设置的比较长(如1min),就发送一次请求后若服务器端不是立刻有新内容推送过来还能响应。

http本质还是一个半双工协议,因此像游戏这种需要大量主动发送数据的场景还是不适用,而websocket协议就比较解决这个问题。

websocket只在建立连接的时候借用了http,然后就与http没有关系了


四、nginx代理跨域

原理:同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不存在跨越问题。


实现:通过nginx配置代理服务器(域名与test1相同,端口不同)做跳板机,反向代理访问test2接口,且可以修改cookie中test信息,方便当前域cookie写入,实现跨域登录。其实就像开发时跨域的原理。

 配置:

typescript socket 跨平台通信 websocket协议跨域_服务器

 

五、开发时跨域,devServer.proxy(vue-cli代理转发)

浏览器是禁止跨域的,但是服务端不禁止,在本地运行npm run dev等命令时实际上是用node运行了一个服务器,因此proxyTable实际上是将请求发给自己的服务器,再由服务器转发给后台服务器,做了亦曾代理,因为不会出现跨域问题。

我们可以在本地弄个服务器, 然后用服务器请求后台服务器接口地址

vuecli脚手架, 启动了一个webpack开发服务器, 它就能做代理转发

而且前端和这个服务器是同源的都是8080端口,需要修改webpack开发服务器的配置即可

那么:

1.代理服务和前端服务之间由于协议域名端口三者统一不存在跨域问题,可以直接发送请求

2.代理服务和后端服务之间由于并不经过浏览器没有同源策略的限制,可以直接发送请求

这样,我们就可以通过中间这台服务器做接口转发,在开发环境下解决跨域问题,看起来好像挺复杂,其实vue-cli已经为我们内置了该技术,我们只需要按照要求配置一下即可。

那就是这样:

devServer: {
    proxy: {
      // http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html
      '/api': { // 请求相对路径以/api开头的, 才会走这里的配置
        target: 'http://c.m.163.com', // 后台接口域名 我们要代理的真实的接口地址
        changeOrigin: true, // 改变请求来源(欺骗后台你的请求是从http://c.m.163.com)
        pathRewrite: {
          '^/api': '' // 因为真实路径中并没有/api这段, 所以要去掉这段才能拼接正确地址转发请求
        }
      }
    }
  }

//也就是说,客户端给代理服务器发送请求,客户端然后再向后端请求