拓展边界:前端世界的跨域挑战
目录
什么是跨域
概念
同源策略及限制内容
常见跨域场景
如何解决跨域
CORS
Nginx代理跨域
Node中间件代理跨域
WebSocket
postMessage
JSONP
其他
什么是跨域
概念
在此之前,我们了解一下一个域名地址的组成:
跨域指的是在网络安全中,由于浏览器的同源策略(Same-Origin Policy)限制,当一个网页的协议、域名或端口与另一个网页的协议、域名或端口不同时,就存在跨域问题。如果缺少同源策略的限制,可能会导致安全隐患,如跨站脚本攻击(XSS)或跨站请求伪造(CSRF)等。
同源策略及限制内容
同源策略是浏览器的一项安全机制,它限制了来自不同源的脚本对当前文档的访问。同源策略要求资源必须来自同一个源(即协议、域名和端口相同),并限制了对以下内容的访问:
-
Cookie、LocalStorage、IndexedDB 等存储性内容:不允许在不同源之间读取或写入这些数据。
-
DOM 节点:不允许获取来自不同源的 DOM 元素。
-
AJAX 请求发送后的响应数据:如果发起了跨域的 AJAX 请求,浏览器会阻止读取其响应内容。
但是有三个标签允许跨域加载资源,它们不受同源策略限制:
<img src=XXX>
<link href=XXX>
<script src=XXX>
常见跨域场景
跨域存在于协议、子域名、主域名、端口号中任何一个不相同时。即使两个不同的域名指向同一个 IP 地址,只要其中任何一部分不同,就被视为不同源。
两个重要点:
- 协议和端口造成的跨域问题需要后端处理,前端无法解决。
- 浏览器在判断跨域时主要依据 URL 的首部,即协议、域名和端口必须匹配。
跨域并不是指请求发不出去,而是浏览器限制了读取来自其他域名下内容的安全策略。例如,Ajax 请求会被浏览器拦截响应数据,但表单提交不会获取新内容,所以可以发起跨域请求。同样,跨域并不能完全阻止 CSRF,因为请求依然会发送出去,只是浏览器会拦截响应。
如何解决跨域
CORS
CORS 通信过程都是浏览器自动完成,需要浏览器(都支持)和服务器都支持,所以关键在只要服务器支持,就可以跨域通信,CORS请求分两类:简单请求和非简单请求。
CORS请求默认不包含Cookie以及HTTP认证信息,如果需要包含Cookie,涉及跨域请求携带 Cookie 信息时需要一些特殊设置,其中涉及到 CORS 的头部设置以及前端代码的配置。
假设有两个域名:https://example.com
和 https://api.example.com
,前者是网页的域名,后者是提供 API 的域名。下面是一个示例,演示如何设置跨域请求以在包含 Cookie 的情况下进行:
后端设置 CORS 头部
在 API 的响应中设置 CORS 相关头部:
// Express 示例
const express = require('express');
const app = express();// 设置允许跨域请求的域名和允许携带 Cookie
app.use((req, res, next) => {res.header('Access-Control-Allow-Origin', 'https://example.com');res.header('Access-Control-Allow-Credentials', 'true');next();
});// 处理其他路由或请求
// ...app.listen(3000);
前端发送带有 withCredentials 的请求
在前端,如果想要在跨域请求中携带 Cookie,需要在 XMLHttpRequest 或 Fetch 请求中设置 withCredentials
为 true
:
使用 XMLHttpRequest 的示例:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.withCredentials = true; // 允许携带 Cookie
xhr.send();
或者使用 Fetch API:
fetch('https://api.example.com/data', {method: 'GET',credentials: 'include', // 允许携带 Cookie
});
上述代码中的关键点在于将 withCredentials 或 credentials: 'include' 设置为 true,这样浏览器就会在请求中包含当前页面的 Cookie 信息。但要确保后端 API 设置了正确的 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 头部,并且不要使用 * 通配符,而是指定了明确的允许跨域的域名。
简单请求
简单请求指的是符合一定条件的跨域请求类型,在这种请求下,浏览器会自动在头部中添加 Origin 字段,表示请求的来源域,服务器根据这个来源决定是否允许请求。满足以下两个条件之一的请求被认为是简单请求:
1.请求方法是 HEAD、GET、POST 之一
2.请求头信息不超过一定限制。允许的请求头包括:
-
Accept
-
Accept-Language
-
Content-Language
-
Last-Event-Id
-
Content-Type:允许的值为 application/x-www/form/urlencoded、multipart/form-data、text/plain 之一。
这些条件主要为了兼容早期的表单提交方式,因为历史上表单提交一直可以跨域。
在这样的简单跨域请求中,服务器至少需要设置 Access-Control-Allow-Origin
头部来允许特定来源的请求。如果服务器认可请求,会在响应中返回以下必要的 CORS 头部:
Access-Control-Allow-Origin | 这个字段是必须的,它指定了允许访问的来源域,一般是请求中 Origin 字段的值,但也可以是通配符 *,表示允许任意来源。 |
Access-Control-Allow-Credentials | 这个字段是可选的,表示是否允许发送 Cookie。如果需要跨域请求携带身份凭证(比如 Cookie 或 HTTP 认证信息),服务器需要设置这个字段为 true。 |
Access-Control-Expose-Headers | 这个字段是可选的,它指定了响应中可以被前端访问的其他头部信息。 |
Content-Type | 表示响应的文档类型和字符编码。 |
简单请求的处理相对较为简单,但需要服务器允许特定的跨域访问并设置相应的 CORS 头部来确保安全。
非简单请求
非简单 CORS 请求指的是不符合简单请求条件的跨域请求,如使用了 PUT 或 DELETE 方法,或者请求的 Content-Type 是 application/json 等。对于这样的请求,浏览器会在正式发起请求之前先发送一个 OPTIONS 类型的预检请求。
预检请求的目的是向服务器查询是否允许来自网页所在域名的请求,并了解可以使用哪些额外的头信息字段。这个预检请求(OPTIONS 请求)的头部信息包括:
- Origin: 标识请求来自哪个域,是必须的字段。
- Access-Control-Request-Method: 列出 CORS 请求会用到的 HTTP 方法,也是必须的字段。
- Access-Control-Request-Headers: 指定 CORS 请求会额外发送的头信息字段,用逗号隔开。
服务器收到这个预检请求后,根据收到的信息判断是否允许这个请求,如果允许,则返回相应的 CORS 头部信息。除了允许特定的跨域请求,服务器还可以在响应头部中添加 Access-Control-Max-Age 字段来缓存预检请求的结果,减少后续请求的预检次数。这个缓存只对完全一样的 URL 生效,超出缓存时间后,再次发起相同的跨域请求仍会触发预检请求。
Nginx代理跨域
Nginx可以用作反向代理服务器,来解决跨域问题。它可以代理客户端的请求,并将请求发送到目标服务器,再将目标服务器的响应返回给客户端。这种方法类似于 CORS 跨域原理,但是它是通过服务器端进行设置,而不是在浏览器端进行设置。
以下是一个简单的 Nginx 配置示例,用于处理跨域请求:
server {listen 81;server_name www.domain1.com;location / {# 设置反向代理proxy_pass http://xxxx1:8080;# 修改 Cookie 中的域名proxy_cookie_domain www.xxxx1.com www.xxxx2.com;# 添加头部信息以处理跨域请求add_header Access-Control-Allow-Origin http://www.xxxx2.com; # 当前端只跨域不带 Cookie 时,可以使用 * add_header Access-Control-Allow-Credentials true;}
}
这段配置的作用如下:
proxy_pass 指令用于指定反向代理的目标服务器地址。proxy_cookie_domain 用于修改代理服务器返回的响应中的 Cookie 中的域名,将它从源域名修改为目标域名,确保 Cookie 在跨域时仍然有效。add_header 指令用于添加响应头部信息,其中 Access-Control-Allow-Origin 允许特定来源的跨域请求,Access-Control-Allow-Credentials 表示是否允许请求携带身份凭证(例如 Cookie)。
这种方法通过 Nginx 作为代理服务器,处理了跨域请求的响应头部,允许指定的域名进行跨域请求。这样就可以在不修改前端代码的情况下,实现跨域请求的需求。
Node中间件代理跨域
在 vue.config.js
文件中,可以通过配置 devServer
的 proxy
选项实现代理转发:
module.exports = {// 其他配置...devServer: {proxy: {[process.env.VUE_APP_BASE_API]: {target: 'http://xxxx', // 代理跨域目标接口ws: true,changeOrigin: true,pathRewrite: {['^' + process.env.VUE_APP_BASE_API]: ''}}}}
}
-
proxy 字段用于配置代理。process.env.VUE_APP_BASE_API 是 Vue 项目中定义的环境变量,表示需要被代理的请求路径前缀。
-
target 指定了代理的目标地址,即请求将会被代理到这个地址下。
-
ws 表示是否代理 WebSocket。
-
changeOrigin 设置为 true 后,可以突破浏览器的同源策略,允许跨域。
-
pathRewrite 允许对请求路径进行重写,将匹配到的路径前缀去掉。比如,如果请求路径是 /api/user,经过 pathRewrite 后就会变成 /user,将前缀 /api 去掉了。
当使用 Node 中间件进行代理跨域时,你可以使用 http-proxy-middleware 包来创建一个代理服务器,让后端服务(如 Express)处理跨域请求。这个中间件可以在 Express 应用程序中使用,允许你在服务器端修改请求和响应,以便处理跨域问题。
下面是一个在 Express 中使用 http-proxy-middleware 中间件的简单示例:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');const app = express();app.use('/', createProxyMiddleware({ // 代理跨域目标接口 target: 'http://xxxx:8080', changeOrigin: true, // 修改响应头信息,实现跨域并允许带cookie onProxyRes: function(proxyRes, req, res) { res.header('Access-Control-Allow-Origin', 'http://xxxx');res.header('Access-Control-Allow-Credentials', 'true');}, // 修改响应信息中的 cookie 域名 cookieDomainRewrite: 'www.domain1.com' // 可以为 false,表示不修改
})); app.listen(3000);
这段代码做了以下事情:
-
引入了 Express 框架和 http-proxy-middleware。
-
创建了一个 Express 应用。
-
使用 app.use 将 createProxyMiddleware 中间件应用到根路径 /。
-
配置了 createProxyMiddleware,指定了目标服务器的地址 target,开启了 changeOrigin 选项以确保源头地址被更改为目标地址。
-
在 onProxyRes 中修改了响应头部信息,允许跨域并设置了允许携带凭证(如 Cookie)。
-
cookieDomainRewrite 可以用于修改响应信息中的 Cookie 域名,使其在传输中适应跨域情况。
这种方式可以在后端服务器层面对跨域进行处理,允许前端应用向不同域名的后端服务发出请求。
WebSocket
WebSocket是一种在单个 TCP 连接上进行全双工通信的协议,它允许客户端和服务器之间进行实时数据交换。与传统的 HTTP 请求不同,WebSocket 的连接是持久性的,双方可以随时发送数据而不需要等待请求。
在跨域方面,WebSocket协议与传统的 HTTP 请求不同,它不受同源策略的限制。可以使用 ws://(非加密)和 wss://(加密)作为协议前缀,不受同源策略的约束,只要服务器支持 WebSocket,即可与客户端进行通信。
WebSocket请求头中包含 Origin 字段,用于指示请求的来源域。服务器可以检查这个字段来判断是否允许与特定域的客户端建立 WebSocket 连接。如果客户端的来源域在服务器的白名单内,服务器将允许该连接的建立,否则可能会拒绝连接或执行其他安全措施。
通过 WebSocket,服务器和客户端之间可以进行持久的双向通信,这种通信方式适用于实时性要求较高的场景,如在线聊天、实时数据传输等。由于不受同源策略的限制,WebSocket提供了一种跨域通信的可选方案。
下面是一个简单的例子,展示了如何使用 WebSocket 进行跨域通信。
首先,假设有两个域名分别是 domain1.com 和 domain2.com,我们将在 domain1.com 的页面上创建 WebSocket 连接到 domain2.com 的服务器:
在 domain2.com 的服务器端,你需要有一个 WebSocket 服务器,例如基于 Node.js 的 ws 模块,用于监听 WebSocket 连接:
const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) {ws.on('message', function incoming(message) {console.log('Received: %s', message);// 可以回复客户端消息ws.send('Hello, client!');});
});
在 domain1.com
的页面上,你可以使用 JavaScript 来创建 WebSocket 连接到 domain2.com
的服务器:
const socket = new WebSocket('ws://domain2.com:8080'); // WebSocket服务器的地址socket.onopen = function(event) {console.log('WebSocket连接已打开');socket.send('Hello, server!');
};socket.onmessage = function(event) {console.log('收到服务器消息:', event.data);
};socket.onclose = function(event) {if (event.wasClean) {console.log('连接已关闭');} else {console.log('连接断开');}
};socket.onerror = function(error) {console.error('WebSocket连接错误:', error);
};
在这个例子中,domain1.com 的页面通过 WebSocket 连接到了 domain2.com 的服务器,并向其发送了消息。服务器收到消息后可以进行处理,并且也可以通过 WebSocket 向客户端发送消息。
需要注意的是,WebSocket 协议在设计上允许跨域通信,因此不会受到浏览器同源策略的限制。但是,服务器端仍然可以根据自己的逻辑来判断是否接受来自特定来源的连接。
postMessage
postMessage
是 HTML5 中的一项 API,它允许在不同窗口(包括 iframe)或不同来源的文档间进行安全地消息传递。这种通信机制可以用于多种场景:
1️⃣ 页面和新打开的窗口之间的数据传递
2️⃣ 不同窗口(包括不同域的窗口)之间的通信
3️⃣ 页面与嵌套的 iframe 之间的数据传递
4️⃣ 不同源的跨域传递数据
postMessage 接受两个参数:
第一个参数是要发送的数据,可以是字符串、对象等。
第二个参数是指定消息发送的目标窗口的来源。这个参数通常是一个目标窗口的 origin(协议 + 域名 + 端口),也可以是通配符 *(表示任意窗口),或者 /(表示与当前窗口同源的窗口)。
例如,在一个页面中,可以使用以下方式向另一个窗口发送消息:
// 获取目标窗口对象
const targetWindow = window.open('https://example.com', '_blank');// 向目标窗口发送消息
targetWindow.postMessage({ message: 'Hello, window!', value: 42 }, 'https://example.com');
在目标窗口中,可以监听 message
事件来接收来自其他窗口的消息:
// 监听 message 事件
window.addEventListener('message', function(event) {// 判断消息来源是否符合预期if (event.origin === 'https://sending-origin.com') {// 处理接收到的消息console.log('Received message:', event.data);}
});
JSONP
JSONP(JSON with Padding)是一种利用 <script> 标签实现的跨域数据请求方法。其原理是通过动态创建 <script> 标签,向服务器请求数据,并在请求的 URL 中包含一个回调函数名。服务器收到请求后,将数据包裹在回调函数中返回给客户端,从而绕过浏览器的同源策略限制。
JSONP 主要用于 GET 请求,并不适用于其他 HTTP 方法,且存在安全隐患,容易受到 XSS(跨站脚本攻击)的影响。但它有一些优点,比如可以向不支持 CORS 的旧浏览器或不支持跨域请求的网站请求数据。
使用 JSONP 的示例代码如下:
// 创建一个包含回调函数的 URL
const url = 'http://juejin.com/xxx?callback=handleCallback';// 创建一个 script 标签
const script = document.createElement('script');// 设置 script 的 URL
script.src = url;// 将 script 添加到页面中
document.body.appendChild(script);// 定义回调函数,处理从服务器返回的数据
function handleCallback(res) {console.log(res);
}
服务器接收到这个请求后,会将数据放在 handleCallback
函数中返回,例如:
handleCallback({ code: 200, msg: 'success', data: [] });
在客户端,这个函数 handleCallback
将立即执行,从而完成数据的处理和操作。
虽然 JSONP 具有一定的局限性和安全风险,但在某些场景下仍然是一种有效的跨域数据获取方式。
其他
除了以上提到的一些常见的解决跨域的方法以外,还有其他的方式可以来解决这个问题。
1. document.domain + iframe:适用于主域名相同但子域名不同的跨域场景。当两个页面的 document.domain 设置为同一个值(主域名),它们就可以相互通信。但这种方法仅适用于主域名相同的情况。
2. window.name + iframe:利用 iframe 的 window.name 属性,这个属性在不同页面或者不同域名加载后依然保持不变。通过在不同页面的 iframe 中设置和读取 window.name,可以实现跨域通信。window.name 具有持久性,且可以存储较大量的数据。
3. location.hash + iframe:适用于页面间利用 URL 的 hash 部分来传递信息,特别是在 C 页面帮助 A 页面和 B 页面进行通信。通过改变 URL 的 hash 部分来传递信息,在不同页面之间进行简单的数据交换。
这些方法虽然可以解决一些特定的跨域通信问题,但由于它们的特性和限制,通常只适用于特定场景,并且可能存在一些安全性或者容量方面的限制。因此,在使用这些方法时,需要仔细考虑其适用范围和可能带来的安全隐患。
好啦,本文就到这里结束了,感谢阅读~~
相关文章:

拓展边界:前端世界的跨域挑战
目录 什么是跨域 概念 同源策略及限制内容 常见跨域场景 如何解决跨域 CORS Nginx代理跨域 Node中间件代理跨域 WebSocket postMessage JSONP 其他 什么是跨域 概念 在此之前,我们了解一下一个域名地址的组成: 跨域指的是在网络安全中&…...

旅游项目day03
1. 前端整合后端发短信接口 2. 注册功能 后端提供注册接口,接受前端传入的参数,创建新的用户对象,保存到数据库。 接口设计: 实现步骤: 手机号码唯一性校验(后端一定要再次校验手机号唯一性)…...

单片机学习记录(一)
简答题 第1章 1.微处理器、微计算机、CPU、单片机、嵌入式处理器他们之间有何区别? 答:微处理器、CPU都是中央处理器的不同称谓,微处理器芯片本身不是计算机; 单片机、微计算机都是一个完整的计算机系统,单片机是集…...

MacBookPro怎么数据恢复? mac电脑数据恢复?
使用电脑的用户都知道,被删除的文件一般都会经过回收站,想要恢复它直接点击“还原”就可以恢复到原始位置。mac电脑同理也是这样,但是“回收站”在mac电脑显示为“废纸篓”。 如果电脑回收站,或者是废纸篓里面的数据被清空了&…...

Python多线程—threading模块
参考:《Python核心编程》 threading 模块的Thread 类是主要的执行对象,而且,使用Thread类可以有很多方法来创建线程,这里介绍以下两种方法: 创建 Thread 实例,传给它一个函数。派生 Thread 的子类…...

mysql limit
语法 SELECT * FROM TABLE_NAME LIMIT 起始位置,偏移量注: 起始位置从0开始 示例 查询的第1条数据到第100条数据 limit 0,100查询的第101条数据到第200条数据 limit 100,100注意不要用 limit 101,100示例2 limit 语句应放在order by语句后面执行 …...

解决国内Linux服务器无法使用Github的方法
解决思路:修改Host https://www.ipaddress.com/ 利用上面的网站查询github.com和raw.githubusercontent.com的DNS解析的IP地址 最后,修改服务器的/etc/hosts 添加如下两行: 140.82.112.3 github.com 185.199.108.133 raw.githubuserconte…...

动态规划基础(二)最长公共子序列 LCS
讲解求两个串中最长的公共的子序列长度或输出子序列等 poj1458 题目大意 给定两个字符串,要求输出两个字符串中最长公共子序列长度 思路 我们定义 a [ i ] [ j ] a[i][j] a[i][j]为,当字串 s t r 1 str1 str1到 i i i位置,字串 s t r 2 s…...

React配置src根目录@
文章目录 1.打开webpack配置文件2.配置webpack 1.打开webpack配置文件 yarn eject or npm run eject 如果报错了记得提前 git commit一下 2.配置webpack 找到 webpack.config.js 文件在 webpack.config.js 文件中找到 alias 配置在alias里添加: path.resolve(src) , 或者 : pa…...

SQL Povit函数使用及实例
PIVOT函数常用于数据的行转列,同时也可以用此函数实现类似于Excel中的数据透视表的效果。 PIVOT函数 PIVOT 函数的基本语法如下: -- PIVOT 语法 SELECT <非透视的列>,[第一个透视的列] AS <列名称>,[第二个透视的列] AS <列名称>,.…...

Lite AD的安装
1、Lite AD的安装及配置 Lite AD流程: (1)创建一个新的Windows 10,安装tools,再安装ITA组件(安装Lite AD会自动安装VAG/VLB) (2)创建一个新的Windows 10,安…...

限流算法之流量控制的平滑之道:滑动时间窗算法
文章目录 引言简介优点缺点样例样例图样例代码 应用场景结论 引言 在互联网应用中,流量控制是一个重要的组件,用于防止系统过载和保护核心资源。常见的限流算法包括固定窗口算法和滑动时间窗算法。本文将重点介绍滑动时间窗算法,并分析其优缺…...

C语言数据结构——顺序表
(图片由AI生成) 0.前言 在程序设计的世界里,数据结构是非常重要的基础概念。本文将专注于C语言中的一种基本数据结构——顺序表。我们将从数据结构的基本概念讲起,逐步深入到顺序表的内部结构、分类,最后通过一个实…...

网络安全:守护数字世界的盾牌
在当今数字化的时代,网络已经渗透到我们生活的方方面面。从社交媒体到在线银行,从在线购物到工作文件传输,网络几乎无处不在。然而,随着网络的普及,网络安全问题也日益凸显。那么,如何确保我们的数字资产安…...

vue3hooks的使用
hook是钩子的意思,看到“钩子”是不是就想到了钩子函数?事实上,hooks 还真是函数的一种写法。 vue3 借鉴 react hooks 开发出了 Composition API ,所以也就意味着 Composition API 也能进行自定义封装 hooks。 vue3 中的 hooks …...

elementUI+el-upload 上传、下载、删除文件以及文件展示列表自定义为表格展示
Upload 上传组件的使用 官方文档链接使用el-upload组件上传文件 具体参数说明,如何实现上传、下载、删除等功能获取文件列表进行file-list格式匹配代码 文件展示列表自定义为表格展示 使用的具体参数说明文件大小展示问题(KB/MB)文件下载代码…...

供应链安全项目in-toto开源框架详解
引言:in-toto 是一个开源框架,能够以密码学的方式验证构件生产路径上的每个组件和步骤。它可与主流的构建工具、部署工具进行集成。in-toto已经被CNCF技术监督委员会 (Technical Oversight Committee,TOC)接纳为CNCF孵化项目。 1. 背景 由于…...

自己是如何使用单元测试
前言 自己是如何使用单元测试 进行单元测试能够让我们在编写方法的具体实现代码后,能清晰地看到其是否能实现预期的功能,有助于我们及时修正自己方法中存在的bug,以免在后续使用到某方法时出现意想不到的错误。 一、引入单元测试所使用的依赖…...

第二百七十八回
文章目录 1. 概念介绍2. 使用方法2.1 DropdownMenu2.1 DropdownMenuEntry 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何禁止页面跟随手机自动旋转"相关的内容,本章回中将介绍DropdownMenu组件.闲话休提,让我们一起Talk Flutter吧。 1.…...

Java 内存模型深度解析
优质博文:IT-BLOG-CN 一、并发编程模型的两个关键问题 【1】并发中常见的两个问题:线程之间如何通信及线程之间如何同步。通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:内存共享和消息传递&…...

python爬取图片(thumbURL和html文件标签分别爬取)
当查看源代码,发现网址在thumbURL之后时,用此代码: # 当查看源代码,发现网址在thumbURL之后时,用此代码:import requestsheaders {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121…...

MySQL、Oracle 常用SQL:建表、建视图、数据增删改查、常用condition
目录 1 MySQL、Oracle 建表语句整理1.1 MySQL 建表1.2 Oracle 建表1.3 补充1.3.1 主键:新增、删除1.3.2 字段:新增、修改、删除 2 MySQL、Oracle 建视图3 数据:增删改查3.1 插入数据3.1.1 MySQL、Oracle 插入一条数据3.1.2 MySQL、Oracle 插入…...

Docker(八)高级网络配置
作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! 高级网络配置 注意:本章属于 Docker 高级配置,如果您是初学者,您可以暂时跳过本章节,直接学习…...

VUE--- ref refs
ref & refs 的作用:用于获取dom元素或组件实例,也可用于组件组件间数据的获取和修改 ref & refs 与querySelector的区别: ● ref & refs 查找的范围是当前组件内,更加精确稳定 ● querySelector 查找的范围是整个页面…...

微信小程序之WXML 模板语法之数据绑定、事件绑定、wx:if和列表渲染
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…...

maven导入无法拉取所需依赖
maven导入无法拉取所需依赖 1.原因2.解决搞定收工! 1.原因 公司使用的是gradle,配置的私有云,maven里面配置私有云完全使用不了,无论配置国内还是国外的,导入的项目报错拉不到jar包。 <mirror><id>mirro…...

【2023-08-20】字节跳动秋招笔试四道编程题解
恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经。 作者@TechGuide【全网同名】 订阅专栏【进阶版】2023最新大厂笔试真题 & 题解,不容错过的宝藏资源! 第一题:最小交换次数 题目描述 小盖将n个珠子排成一排,然后将它们串…...

VPS网站发布-个人网站搭建与部署-个人简历网站示例-个人简历网站案例-网站推广
文章目录 1. 个人网站搭建指南1.1 网站示例 | 个人网站 | 个人简历模版 | 个人简历网站 | 网站案例1.2 准备工具 2. 网页部署教程(ubuntu)2.1 购买域名2.2 购买VPS2.3 部署工具 Apache || Nginx2.1.1 网页相关文件上传到github库2.1.2 在VPS中执行一键部…...

INTEWORK—PET 汽车软件持续集成平台
产品概述 INTEWORK-PET-CI是经纬恒润自主研发的汽车软件持续集成&持续交付平台,在传统的持续集成基础上深化了研运一体化(DevOps)的概念,将嵌入式软件中的拉取代码、检查、构建、测试、版本管理以及发布交付等环节串联起来&am…...

【Git】 取消上一次commit或push
一、取消上一次commit 如果你需要取消上一次的 Git 提交,有几个不同的方法可以实现。其中包括撤消提交、提交到新的分支、使用 Git 回滚等等。 下面介绍三种方法: 方法1:使用 Git reset 使用 Git reset 命令来取消上一次提交: …...