前端跨域解决方案

news2025/1/21 15:21:51

文章目录

  • 1.同源政策
  • 2.跨域解决方案
    • 2.1 CORS
      • 普通跨域请求:只需服务端设置Access-Control-Allow-Origin即可
      • 携带cookie跨域请求:前后端都需设置
    • 2.2 JSONP
      • 原理
      • 缺点
      • 数据格式
      • jsonp跨域实现
    • 2.3 postMessage跨域
    • 2.4 WebSocket
        • 属性:
        • 事件:
        • 使用
    • 2.5 代理跨域:开启一个代理服务器实现数据转发
    • 2.6 iframe系列
  • 3. 参考资料

1.同源政策

  1. 如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
    http://www.example.com:8080/dir/page.html
    http://www.example.com/page.html不跨域
    http:协议
    www:子域名
    example:主域名
    8080:端口号(http默认8080)

  2. 同源策略的限制:
    Cookie、LocalStorage 和 IndexDB 无法读取
    AJAX 请求不能发送

  3. 跨域是浏览器为了安全而实施的同源政策导致的

2.跨域解决方案

跨域报错:在这里插入图片描述

2.1 CORS

有几个关键的响应头字段:

a、Access-Control-Allow-Origin:必填,表示可以允许请求的来源。可以填写具体的源名称,也可以填写*表示允许任何源请求。

b、Access-Control-Allow-Methods:表示允许的请求方法列表。

c、Access-Control-Allow-Credentials:一个布尔值,表示是否允许发送cookie。默认情况下,cookie 不包含在 CORS 请求中。如果设置为 true,则表示服务器具有显式权限。Cookies 可以包含在请求中并一起发送到服务器。

d、Access-Control-Allow-Headers:其指明了实际请求中允许携带的首部字段。CORS请求时,XMLHttpRequest对象的getresponseheader()方法只能获取六个基本字段:缓存控制、内容语言、内容类型、过期时间、最后修改时间和pragma。如果要获取其他字段,则必须在访问控制公开标头中指定它们。

e、Access-Control-Max-Age:预检请求的有效期。在此期间,无需再次发送预检请求。

普通跨域请求:只需服务端设置Access-Control-Allow-Origin即可

Access-Control-Allow-Origin: *表示该资源可以被任意外域访问,若设置具体的值则只可与设置的值跨域

备注: 当响应的是附带身份凭证的请求时( cookie ),服务端 必须 明确 Access-Control-Allow-Origin 的值,而不能使用通配符“*”。

携带cookie跨域请求:前后端都需设置

如果设置 Access-Control-Allow-Origin: * ,不管withCredentials有没有设置,cookie也不会携带

前端设置:
若使用原生ajax

//使用ajax时加上withCredentials属性为true以携带cookie
xhr.withCredentials = true;

若用jQuery ajax

$.ajax({
   url:'',
   xhrFields: {
       withCredentials: true    // 前端设置是否带cookie
   },
   crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
});

服务器端设置:

// 允许跨域访问的域名:若有端口需写全,注意不能用*
"Access-Control-Allow-Origin""http://www.domain1.com" 

// 允许前端带认证cookie
"Access-Control-Allow-Credentials""true"

2.2 JSONP

原理

JSONP主要就是利用了script标签没有跨域限制的这个特性来完成的,它可以通过src填写目标地址,发送一个带回调参数的get请求。服务器将接口返回数据分割成回调函数返回给浏览器。浏览器解析并执行就可得到服务器返回的数据。

缺点

只支持get请求,不支持post请求。适用于加载不同域名的js、css、img等静态资源

数据格式

键值对,要加双引号,除了值为数字时不用加双引号

[
  {
    "id":1,
    "name":"Rick",
    "email":"rick@gmail.com"
  },
  {
    "id":2,
    "name":"Glenn",
    "email":"glenn@gmail.com"
  }
]

jsonp跨域实现

若用原生Ajax(点击按钮向服务器发送请求):
script.src的callback后为回调函数的名字

      var btn = document.getElementById('btn');
      function jsonpCores(url) {
        var script = document.createElement('script');
        script.src = 'url?callback=callbackName';
        // 将script标签追加到页面中
        document.body.appendChild(script);
        window.callbackName= function(res){
            console.log(res);
        }
        // 将head中的script标签删除掉,防止多个script标签导致代码冗余
         document.body.removeChild(script);
         console.log('123');
        };
    
      btn.onclick =jsonpCores('');

若用jQuery ajax

$.ajax({
				url: '',
				method:'get',
				// 回调函数的名称
				jsonpCallback: 'fn',
				dataType: 'jsonp', //设置请求方式为jsonp
			})

若用vue.js

this.$http.jsonp('url', {
    params: {},
    jsonp: 'fn' //回调函数名
}).then((res) => {
    console.log(res); 
})

2.3 postMessage跨域

语法:otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow: 其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames
message:将要发送到其他 window的数据
targetOrigin:指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI(最好填一个确切的url)。
transfer (可选):是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权

接收其他域传来的数据:
window.addEventListener("message", function(e){ console.log(e.data) },false);

message 的属性有:
data:从其他 window 中传递过来的数据对象。
origin:调用 postMessage 时消息发送方窗口的 origin . 例如 “https://example.org (隐含端口 443)”。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。
source:对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。

2.4 WebSocket

WebSocket 对象提供了用于创建和管理 WebSocket 连接,以及可以通过该连接发送和接收数据的 API。
使用 WebSocket() 构造函数来构造一个 WebSocket

var aWebSocket = new WebSocket(url [, protocols]);
url:要连接的URL;WebSocket服务器将响应的URL。
protocols 可选:一个协议字符串或者一个包含协议字符串的数组。这些字符串用于指定子协议,这样单个服务器可以实现多个WebSocket子协议(例如,您可能希望一台服务器能够根据指定的协议(protocol)处理不同类型的交互)。如果不指定协议字符串,则假定为空字符串。

属性:

WebSocket.onclose 用于指定连接关闭后的回调函数。
WebSocket.onerror 用于指定连接失败后的回调函数。
WebSocket.onmessage 用于指定当从服务器接受到信息时的回调函数。
WebSocket.onopen 用于指定连接成功后的回调函数。
WebSocket.url (只读) WebSocket 的绝对路径。

事件:

使用 addEventListener() 或将一个事件监听器赋值给本接口的 oneventname 属性,来监听下面的事件。
close:当一个 WebSocket 连接被关闭时触发。
error:当一个 WebSocket 连接因错误而关闭时触发,例如无法发送数据时。
message:当通过 WebSocket 收到数据时触发。
open:当一个 WebSocket 连接成功时触发。

使用

前端

const socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', function (event) {
    socket.send('成功连接服务器!'); //向服务器发送数据
});
// Listen for messages
socket.addEventListener('message', function (event) {
    console.log('获取服务器数据 ', event.data);
});
//当不需要再用 WebSocket 连接时调用 WebSocket close()方法
socket.close();

后台

const WebSocket = require("ws");
const server = new WebSocket.Server({ port: 8080 });
server.on("connection", function(socket) {  //建立连接
  socket.on("message", function(data) {  //获取客户端发来的数据
    socket.send(data);
  });
});

2.5 代理跨域:开启一个代理服务器实现数据转发

正向代理帮助客户端访问客户端无法访问服务器本身并将结果返回给客户端。
反向代理从客户端获取请求并将请求转发给其他服务器。
正向代理服务器帮助客户端做事,反向代理服务器帮助其他服务器做事
Nginx反向代理跨域
配置nginx

server {
        listen 80;
        server_name client.test;
        location /api {
            proxy_pass http://localhost:8080;
        }
}

Nodejs中间件代理跨域
用vue框架webpack.config.js配置

module.exports = {
    devServer: {
        historyApiFallback: true,
        proxy: [{
            target: '',  // 代理跨域目标接口
            changeOrigin: true,
            secure: false,  // 当代理某些https服务报错时用
        }]
    }
}

2.6 iframe系列

document.domain +iframe跨域:两个页面都通过js强制设置document domain为基础主域,实现同域
locatin.hash + iframe跨域: a 与b跨域相互通信,通过中间页c来实现,三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。
window. name + iframe跨域:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。
详见:https://segmentfault.com/a/1190000022398875


3. 参考资料

MDN CORS
MDN window.postMessage
MDN WebSocket
Front end cross domain problems and Solutions

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3+vite:本地代理,配置proxy

一、项目:uniappvue3vitets 二、配置文件在vite.config.ts proxy: {/snow: { // 匹配请求路径,localhost:3000/snowtarget: https://www.snow.com/, // 代理的目标地址changeOrigin: true, // 开发模式,默认的origin是真实的 origin:localh…

压缩gltf/glb模型踩坑与解决 three.js DRACOLoader

前言 使用前端three.js加载3d模型过程中,往往会出现模型大小过大导致前端加载时间过长,降低用户体验。 本文所记录的是笔者在使用gltf-pipeline压缩3d模型中踩坑DRACOLoader与解决的一个过程。 所采用的three库版本为 ^0.138.2 解决方案与介绍 通过g…

31.JavaScript数组进阶,一网打尽数组操作函数slice、filter、map、reduce、some、every、find、splice

文章目录数组进阶元素删除(对象方式)splice()删除一个元素删除多个元素截断数组元素替换元素插入返回值负索引slice()concat()forEach()indexOf、lastIndexOf、includesfind、findIndexfiltermapsortreversestr.split()和arr.join()reduce、reduceRightA…

vue在html标签 {{}} 中调用函数的方法

目录 一、问题 1)实现上述需求:有两种方式 2)两种实现方式对比: 二、解决方法(在html渲染时调用函数) 三、总结 注:不想仔细看的,可以直接看有颜色的及代码哟 一、问题 1.在ht…

关于 HbuilderX 运行项目到手机,搜索不到手机解决

注意 本文内,我的 HbuilderX 安装目录都是在 D:\app 目录下,所有关于本文的操作文件都是在 HbuilderX 安装包内。 第一步:打开环境变量,找到系统变量,然后点击编辑。 第二部:配置 HbuilderX 的 adbs 目录…

JS中的位运算

目录 JS中的位运算 JS中的与运算 JS中的或运算 JS中的否(非)运算 计算机中负数的存储方式 JS中的异或运算 JS中位运算的应用场景 位的叠加(开关) JS中的位移运算 左位移 右位移 全右位移 首先了解一下什么是位运算 位…

Vite 配置篇:日常开发掌握这些配置就够了!

不知道有没有这样的兄弟,学习 Vite 的时候,官网上各种配置看的是眼花缭乱。不知道哪些需要掌握,哪些只用简单了解一下。为了提高大家的效率,我把项目中常用的配置梳理了一下分享给大家,希望对你上手 Vite 有所帮助。话…

若依框架前端切换TagView时刷新问题

若依框架点击顶部tag切换时,永远都是刷新的。刷新问题两种情况:普通view切换时刷新及iFrame切换刷新 一、普通view切换时刷新 原因是view的name与在菜单填写的大小写不一致,按若依框架规则,路由地址必须写为 camel 驼峰命名形式&…

前端:Tomcat服务器部署Web项目

文章目录1.1 C/S架构1.2 B/S架构2.1 服务器2.2 常见服务器3.1 Tomcat安装3.2 Tomcat使用3.3 Tomcat配置3.4 Tomcat项目部署4.1 Servlet技术4.2 Servlet配置4.3 配置测试4.4 Servlet部署5.1 IDEA部署1.1 C/S架构 Client / Server客户端/服务器 客户端作为独立程序 图形效果较好…

【面试题】面试官: Vue如何实现权限管理?

我正在参加「掘金启航计划」 一、权限管理 权限管理就是让不同的用户只能访问自己权限内的资源,有以下几种 路由权限,用户登录后只能看到自己权限内的导航菜单,且只能访问自己权限内的路由地址视图权限,用户只能看到自己权限内…

为你心仪的她做一个 “旋转木马“告白相册【零基础纯 CSS3 实现】

💳 效果展示: 旋转相册效果里面就不放女朋友的美照了防止虐狗 🥰🥰🥰,就用个前端技能树的图片代替哈,有需要大家自行替换。 💳 源码获取: 源码我已经上传到了资源里&…

Django web开发(二) - Mysql数据库

文章目录Mysql数据库Mysql的安装(CentOS7)下载修改配置文件Mysql强制重置密码远程可登录数据库管理数据表的管理常用数据类型数据管理添加数据查询数据删除数据修改数据员工管理Python管理数据库添加数据查询数据删除数据修改数据案例: Flask Mysql案例: 查询所有用户Mysql数据…

Three.js 渲染glb,gltf模型(保姆级教程)

1.准备工作 将下列文件在three.js的包中找到,注意的是我这里使用的是模块化版本的,这里不知道模块化的,可以先去看一下es6的模块化。 控制器: OrbitControls.js 加载器:GLTFLoader.js 材质: RoomEnviron…

echarts折线图流动特效的实现(非平滑曲线)

1.实现效果 2.实现原理 echarts官网:series-lines 注意:流动特效只支持非平滑曲线(smooth:false) series-lines路径图: 用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线&#xff…

若依框架:前端登录组件与图像验证码

在上一篇《若依框架:前端项目结构与初始页面渲染流程》中,我们探讨了与“vue.config.js文件配置、.env模式和环境变量配置、vue-router全局导航守卫配置、vue-router路由配置简介”相关的内容,书接上回,我们继续探讨若依前端项目的…

前端实现在线预览Word文件

简介 在项目中遇到了个需求,大致需求这样的:用户在上传文件前需要先预览一下内容,确认内容是否正确,正确的情况下才可以上传; 那么这里面会涉及到一个在上传前的文档的预览操作,下面就记录一下踩坑记录 d…

uni-app ——使用uploadFile上传多张图片

前言:最近的工作中出现了一个功能点,具体写法我在前面的文章中已经阐述过,不过之前的情况是上传图片调用后端的一个接口,整个表单页面提交的时候调用的是另一个接口,我也从中学到了另外的一种方法,写到这里…

UniApp Scroll-View 设置占满下方剩余高度的方法小记

前言:点滴积累,贵在坚持一、布局描述:屏幕分为上下两部分,上面部分高度固定,比如 400rpx(单位可以指定为其他的比如px、upx等,高度也可以自己设定),下面部分为 scroll-vi…

css渐变

1. 线性渐变(是从一个方向到另一个方向的渐变) 属性值:background:linear-gradient(颜色) ✍默认值:从上到下线性渐变: 代码: 结果: ✍ 属性延伸&#x…

axios—使用axios请求REST接口—发送get、post、put、delete请求

文档:GitHub - axios/axios: Promise based HTTP client for the browser and node.js 目录 一、axios发送get请求 简写版get请求 完整版get请求 get请求怎么在路径上携带参数 二、axios发送post请求 简写版post请求 完整版post请求 其他方式发送post请求 三…