了解跨域,看这篇就够了!

一、定义:

跨域又名非同源策略请求,同源指的是相同的协议/域名/端口,三者都要一样才叫同源

二、产生跨域的原因

  • 服务器拆分(这样一拆分后域名就不同了)

     web服务器:处理静态资源,比如为kbs.qq.com
     data服务器:业务逻辑和数据分析,包含数据管理asdasd.qq.com
     图片服务器:image.qq.com
    
  • 调用第三方开源接口,也会产生跨域

三、判断同源和跨域

通过协议、域名、端口三者来判断,只有三者都一样的时候才是同源,其中一项不同就是跨域;

四、跨域方案

1、早期跨域及处理方案(2013年左右)

开发情景:当时代码部署都是部署到同一台服务器上的(同源),但是开发的时候,前端一般都是通过xampp来起一个前端本地的服务,而后端一般给的服务(接口)都是类似于http://api.qq.com这样的真实域名,所以我们这样直接请求数据就相当于跨域了,直接请求是请求不到的;
解决方法:所以当时有一种办法就是通过修改本地host文件,把本地的域名和真实的域名进行关联,这样访问就模拟了同源的效果;

127.0.0.1:3000   http://api.qq.com

2、JSONP

实现原理:
在这里插入图片描述
实现原理及思路解析:

首先客户端会创建一个script标签,通过它的src属性来请求后端的一个接口数据,为什么选择script标签呢?因为script标签的不跨域特性,然后同时将本地创建的一个全局函数,通过callback的方式拼参数拼在地址后面,这时服务器接受到了客户端的请求,它会先开始准备要返回给客户端的数据(data,json格式),然后给客户端返回数据,它返回的是一个类似于调用func函数的字符串,将数据拼在函数的()内,然后当客户端接受到了返回数据(一个函数执行式的字符串),通过解析后,相当于直接执行了全局的func函数,这个解析执行操作是浏览器自身操作的,我们不用管,同时也将data传到了这个函数中,从而达到了客户端向服务器请求数据得到返回的这么一个过程;

注意:
1、这个func函数必须是全局函数,不然返回后不能执行;
2、这种jsonp的方式处理跨域,必须得到服务器端的处理,说白了就是,如果服务器端不接收callback,不给你返回这样格式的字符串数据,你前端再怎么搞也没用;

代码实战:

//html文件,引入两个js文件

<!DOCTYPE html>
<html lang="en">
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js" ></script>
<script src="./index.js"></script>
<head>
    <meta charset="UTF-8">
    <title>fetch</title>
</head>
<body>
</body>
</html>
//本地index.js,然后再index.html中引入该js文件和jquery

$.ajax({          // 这里通过jquery的ajax方法来实现jsonp跨域,jquery中的ajax封装了jsonp的功能,只要传dataType:“jsonp”即可
    url:'http://127.0.0.1:8001/list',
    method:"get",
    dataType:"jsonp",
    success:(res)=>{
    console.log(res) 
    }
})
//自己写的一个简单web服务

const express = require('express');
const app =express();
app.listen('8001',()=>{
    console.log('ok');
});
app.get('/list',(req,res)=>{
    const {callback=Function.prototype}=req.query;
    const data= {
        code: 0,
        message: '你好'
    };
    res.send(`${callback}(${JSON.stringify(data)})`);
});

缺点:

  1. jsonp这种通过src方式请求的都是资源文件请求,所以有一个明显的问题就是只支持get请求;
  2. jsonp安全性也不高,url容易被劫持,或者服务器返回一个木马程序,浏览器执行就中毒了;

3、CORS跨域资源共享

客户端:还是正常发起请求(ajax,fetch);

服务端:要设置响应头参数,以及处理options试探性 预请求处理
在这里插入图片描述
在这里插入图片描述
要设置的参数有如下: 允许的请求源、是否允许携带凭证、允许的请求头、允许的请求方法

注意: 这里有个注意点,允许源这里有两种设置,一种是还有一种是唯一的一个请求地址,当你设置为时说明,此时允许任务地址来访问该资源,但是此时请求就不能携带cookie了,因为浏览器考虑安全性,如果设置为单一地址,此时时可以携带cookie的;

4、http proxy(代理)

简单原理:
在webpack中可以通过安装webpack-dev-server起一个服务,在webpack.config.js配置文件中的devServer属性中配置相关proxy设置,
它的意思就是说,后续只要是以’/'开头的请求,都会前面自动带上target后面的这个域名, 然后配置了changeOrigin:true,这句话的意思就是说webpack-dev-server会起一个中层代理,相当于用node写了一个中间件,相当于我们客户端的请求会先到这个中间件,中间件中帮我们进行了跨域请求处理,然后把跨域处理后的数据再返回给客户端;
在这里插入图片描述
5、Ngnix反向代理=》不需要前端做什么,了解

6、postMessage方式

概述:
就是通过window.postMessage发送消息,然后通过onMessage方法接受消息,本地页面之间的数据传递,同理换成客户端和服务器之间就相当于也是一种解决跨域的方式;

A页面代码:

在这里插入图片描述

B页面代码:


7、socket.io(websocket协议跨域)

客户端:
在这里插入图片描述
服务端:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ronychen’s blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值