前端怎么解决跨域

JSONP

jsonp的原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,将本地的全局函数通过callback传到服务器,服务端将接口返回数据拼凑到callback函数中,返回给客服端

实现思路 

 服务端的代码:

let express = require('express');
app = express();
app.listen('8001', () => {
  console.log('ok');
})
app.get('/list', (req,res) => {
  let { callback } = req.query;
  let data = {
    code: 0,
    message:'发送的数据'
  }
  res.send(`${callback}(${JSON.stringify(data)}`)
})

客户端代码

<script>
    let script = document.createElement('script');
    script.type = 'text/javascript';
    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);
    // 回调执行函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
</script>

jsonp的缺点:只能发送get一种请求。安全性低

CORS 跨域资源共享

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

客服端:发送请求

服务端通过配置一些头信息 Access-Control-Allow-Origin:必选

 所有的cors请求都会预先发一个options请求 发送真正请求前先发一个试探性请求

缺点是允许源只能写一个地址 或者直接写* 写*不安全并且不允许携带cookie了

nginx反向代理

不需要前端处理

http proxy

webpack 配置 webpack-dev-server配置 (node启了一个本地服务器)

devServer:{
    port:3000,
    progress:true,
    contentBase:'./bulid',
    proxy:{
        '/':{ 以/ 开头的路径都转到target路径下
            traget:'http://127.0.0.1:3001',
            changeOrigin:true
         }
    }
}

Window.postMessage

实现跨源通信,两个不同页面的脚本实现通信

A页面

<body>
  <iframe id="iframe" style="display:none" src="http://127.0.0.1:1002/MESSAGE/b.html"></iframe>
  <script>
    iframe.onload=function(){
      iframe.contentWindow.postMessage('发送的数据','http://127.0.0.1:1002')
    }
    // 监听b页面传过来的数据
    window.onmessage = function(ev){
      console.log(ev.data)
    }
  </script>
</body>

B页面

<script>
//=> 监听A发送过来的信息
window.onmessage = function(ev){
    console.log(ev.data)
    //=>ev.source:A
    ev.source.postMessage(ev.data+'@@@',ev.origin)
}
</script>

WebSocket协议跨域

WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯

如果想完全搭建一个 WebSocket 服务端比较麻烦,又浪费时间。所以一般会使用Socket.io 这个库,

简单实现一个聊天功能:

服务端:

let express = require('express');
let app = express();
let server = require('http').createServer(app);
let io = require('socket.io')(server);
let path = require('path');
 
app.use('/', (req, res, next) => {
  res.status(200).sendFile(path.resolve(__dirname, 'index.html'));
});
 
// 开启 socket.io
io.on('connection', (client) => {
 
  // 如果有新客户端进来,显示 ID
  console.log(`客户端 ID:${client.id}`);
 
  // 监听客户端的输入信息
  client.on('channel', (data) => {
    console.log(`客户端 ${client.id} 发送信息 ${data}`);
    io.emit('broadcast', data);
  });
 
  // 判断客户端是否关闭
  client.on('disconnect', () => {
    console.log(`客户端关闭:${client.id}`);
  });
});
 
server.listen(3000, () => {
  console.log('服务监听 3000 端口');
});

客户端:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Socket.io</title>
  <script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.slim.js"></script>
</head>
<body>
  <input type="text" id="input">
  <button id="btn">send</button>
  <div id="content-wrap"></div>
  <script>
    window.onload = function () {
      let inputValue = null;
 
      // 连接 socket.io
      let socket = io('http://localhost:3000');
      // 将创建的信息以添加 p 标签的形式展示成列表
      socket.on('broadcast', data => {
        let content = document.createElement('p');
        content.innerHTML = data;
        document.querySelector('#content-wrap').appendChild(content);
      })
 
      // 设置输入框的内容
      let inputChangeHandle = (ev) => {
        inputValue = ev.target.value;
      }
      // 获取输入框并监听输入
      let inputDom = document.querySelector("#input");
      inputDom.addEventListener('input', inputChangeHandle, false);
 
      // 当用户点击发送信息的时候,进行数据交互
      let sendHandle = () => {
        socket.emit('channel', inputValue);
      }
      let btnDom = document.querySelector("#btn");
      btnDom.addEventListener('click', sendHandle, false);
 
      // 打页面卸载的时候,通知服务器关闭
      window.onunload = () => {
        btnDom.removeEventListener('click', sendHandle, false);
        inputDom.removeEventListener('input', inputChangeHandle, false);
      }
    };
  </script>
</body>
</html>

用on监听,用emit发送一个指令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值