从零手写实现 nginx-23-nginx 对于 cookie 的操作
前言
大家好,我是老马。很高兴遇到你。
我们为 java 开发者实现了 java 版本的 nginx
https://github.com/houbb/nginx4j
如果你想知道 servlet 如何处理的,可以参考我的另一个项目:
手写从零实现简易版 tomcat minicat
手写 nginx 系列
如果你对 nginx 原理感兴趣,可以阅读:
从零手写实现 nginx-01-为什么不能有 java 版本的 nginx?
从零手写实现 nginx-02-nginx 的核心能力
从零手写实现 nginx-03-nginx 基于 Netty 实现
从零手写实现 nginx-04-基于 netty http 出入参优化处理
从零手写实现 nginx-05-MIME类型(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)
从零手写实现 nginx-06-文件夹自动索引
从零手写实现 nginx-07-大文件下载
从零手写实现 nginx-08-范围查询
从零手写实现 nginx-09-文件压缩
从零手写实现 nginx-10-sendfile 零拷贝
从零手写实现 nginx-11-file+range 合并
从零手写实现 nginx-12-keep-alive 连接复用
从零手写实现 nginx-13-nginx.conf 配置文件介绍
从零手写实现 nginx-14-nginx.conf 和 hocon 格式有关系吗?
从零手写实现 nginx-15-nginx.conf 如何通过 java 解析处理?
从零手写实现 nginx-16-nginx 支持配置多个 server
从零手写实现 nginx-17-nginx 默认配置优化
从零手写实现 nginx-18-nginx 请求头+响应头操作
从零手写实现 nginx-19-nginx cors
从零手写实现 nginx-20-nginx 占位符 placeholder
从零手写实现 nginx-21-nginx modules 模块信息概览
从零手写实现 nginx-22-nginx modules 分模块加载优化
从零手写实现 nginx-23-nginx cookie 的操作处理
前言
大家好,我是老马。
这一节我们将配置的加载,拆分为不同的模块加载处理,便于后续拓展。
1. proxy_set_header Cookie 指令
介绍下 nginx proxy_set_header Cookie "admin_cookie=admin_value; $http_cookie"; 操作 cookie 的指令
在 Nginx 配置文件中,proxy_set_header 指令用于设置在代理请求中传递的 HTTP 头部字段。
通过 proxy_set_header 可以在将请求转发给上游服务器时添加、修改或删除请求头部字段。
具体来说,proxy_set_header Cookie "admin_cookie=admin_value; $http_cookie"; 这条指令用于修改请求头中的 Cookie 字段。
它将一个新的 cookie(admin_cookie=admin_value)添加到现有的请求 cookie 中。详细解释如下:
proxy_set_header指令:这是 Nginx 用来设置请求头部字段的指令。Cookie:这是要设置的头部字段名称。在这种情况下,设置的是 HTTP 请求的Cookie头部。"admin_cookie=admin_value; $http_cookie":这是要设置的头部字段值。admin_cookie=admin_value:这是要添加的新 cookie 值。admin_cookie是 cookie 的名称,admin_value是它的值。;:分号用来分隔多个 cookie。$http_cookie:这是一个 Nginx 的内置变量,它包含了当前请求中的所有 cookie 值。
通过这条指令,Nginx 会在转发请求到上游服务器之前,将一个新的 cookie 添加到现有的 cookie 中。这样上游服务器就会收到一个包含新添加的 admin_cookie=admin_value 的 Cookie 头部。
示例配置片段如下:
server {listen 80;server_name example.com;location / {proxy_pass http://backend_server;proxy_set_header Cookie "admin_cookie=admin_value; $http_cookie";}
}
在这个示例中,当客户端向 example.com 发起请求时,Nginx 会将请求转发给 backend_server,并在请求头部的 Cookie 字段中添加一个新的 admin_cookie=admin_value。
其他相关的 Nginx 指令
proxy_pass:用于定义请求转发到的上游服务器。proxy_set_header:用于设置转发请求的头部字段。
注意事项
- 安全性:在操作 cookie 时需要注意安全性,尤其是涉及敏感信息的 cookie。
- 兼容性:确保上游服务器能够正确处理添加的 cookie。
- 配置顺序:
proxy_set_header通常放在location或server块中,并在proxy_pass指令之前。
通过合理配置 proxy_set_header 指令,可以在 Nginx 中灵活地操作 HTTP 请求头部,满足各种代理需求。
netty 如何实现 对于 cookie 的新增/修改/删除?
这个我们原来就支持了
/*** # 增加或修改请求头* proxy_set_header X-Real-IP $remote_addr;* # 删除请求头* proxy_set_header X-Unwanted-Header "";** @param configParam 参数* @param context 上下文*/@Overridepublic void doBeforeDispatch(NginxCommonConfigParam configParam, NginxRequestDispatchContext context) {List<String> values = configParam.getValues();// $ 占位符号后续处理String headerName = values.get(0);String headerValue = values.get(1);FullHttpRequest fullHttpRequest = context.getRequest();// 设置HttpHeaders headers = fullHttpRequest.headers();if (StringUtil.isEmpty(headerValue)) {headers.remove(headerName);logger.info(">>>>>>>>>>>> doBeforeDispatch headers.remove({})", headerName);} else {// 是否包含if (headers.contains(headerName)) {headers.set(headerName, headerValue);logger.info(">>>>>>>>>>>> doBeforeDispatch headers.set({}, {});", headerName, headerValue);} else {headers.add(headerName, headerValue);logger.info(">>>>>>>>>>>> doBeforeDispatch headers.set({}, {});", headerName, headerValue);}}}
proxy_cookie_domain 指令
解释
proxy_cookie_domain 是 Nginx 的一个指令,用于修改代理服务器响应中的 Set-Cookie 头部的 Domain 属性。
这个指令通常用于在反向代理配置中,当上游服务器设置的 Domain 属性与客户端访问的域名不一致时,通过重写 Domain 属性来解决跨域问题。
语法
proxy_cookie_domain [上游服务器的域名] [要重写为的域名];
- 上游服务器的域名:指定要匹配并重写的
Domain属性值。 - 要重写为的域名:指定新的
Domain属性值。
默认值
proxy_cookie_domain off;
如果不设置 proxy_cookie_domain,则默认不对 Set-Cookie 头部的 Domain 属性进行任何修改。
配置范围
该指令可以在 http、server 或 location 块中配置。
示例
假设我们有一个后端服务器 backend.example.com,它在设置 Cookie 时将 Domain 属性设为 backend.example.com。
但是,客户端访问的是 www.example.com。
我们可以使用 proxy_cookie_domain 来重写 Domain 属性,以便客户端能够正确地接收和发送这些 Cookie。
http {server {listen 80;server_name www.example.com;location / {proxy_pass http://backend.example.com;proxy_cookie_domain backend.example.com www.example.com;}}
}
在这个配置中,当上游服务器 backend.example.com 在响应中返回 Set-Cookie 头部时:
Set-Cookie: sessionid=abcd1234; Domain=backend.example.com; Path=/
Nginx 会将其重写为:
Set-Cookie: sessionid=abcd1234; Domain=www.example.com; Path=/
使用场景
- 跨域 Cookie 共享:当后端服务器和客户端使用不同的域名时,通过
proxy_cookie_domain重写Set-Cookie头部的Domain属性,使 Cookie 能够在客户端域名下有效。 - 域名变更:如果网站的域名发生变化,通过该指令可以确保旧域名设置的 Cookie 仍然有效。
- 子域名问题:在使用子域名时,可以通过该指令将所有子域名的 Cookie 统一到主域名下。
注意事项
- 安全性:确保重写的域名是可信任的,以防止 Cookie 被不当共享。
- 精确匹配:
proxy_cookie_domain的匹配是精确匹配的,因此需要确保指定的上游服务器域名与实际的Set-Cookie头部中的Domain属性完全一致。
通过合理使用 proxy_cookie_domain 指令,可以有效地解决跨域 Cookie 共享的问题,确保在反向代理场景下的 Cookie 设置和使用正确无误。
如何通过 netty,实现 proxy_cookie_domain 指令特性?
核心实现如下:
/*** 参数处理类 响应头处理** @since 0.20.0* @author 老马啸西风*/
public class NginxParamHandleProxyCookieDomain extends AbstractNginxParamLifecycleWrite {private static final Log logger = LogFactory.getLog(NginxParamHandleProxyCookieDomain.class);@Overridepublic void doBeforeWrite(NginxCommonConfigParam configParam, ChannelHandlerContext ctx, Object object, NginxRequestDispatchContext context) {if(!(object instanceof HttpResponse)) {return;}List<String> values = configParam.getValues();if(CollectionUtil.isEmpty(values) || values.size() < 2) {return;}// 原始String upstreamDomain = values.get(0);// 目标String targetDomain = values.get(1);HttpResponse response = (HttpResponse) object;HttpHeaders headers = response.headers();String setCookieHeader = headers.get(HttpHeaderNames.SET_COOKIE);if (setCookieHeader != null) {Set<Cookie> cookies = ServerCookieDecoder.STRICT.decode(setCookieHeader);Set<Cookie> modifiedCookies = cookies.stream().map(cookie -> {if (upstreamDomain.equals(cookie.domain())) {Cookie newCookie = new DefaultCookie(cookie.name(), cookie.value());newCookie.setDomain(targetDomain);newCookie.setPath(cookie.path());newCookie.setMaxAge(cookie.maxAge());newCookie.setSecure(cookie.isSecure());newCookie.setHttpOnly(cookie.isHttpOnly());return newCookie;}return cookie;}).collect(Collectors.toSet());List<String> encodedCookies = ServerCookieEncoder.STRICT.encode(modifiedCookies);headers.set(HttpHeaderNames.SET_COOKIE, encodedCookies);}logger.info(">>>>>>>>>>>> doBeforeWrite proxy_hide_header upstreamDomain={} => targetDomain={}", upstreamDomain, targetDomain);}@Overridepublic void doAfterWrite(NginxCommonConfigParam configParam, ChannelHandlerContext ctx, Object object, NginxRequestDispatchContext context) {}@Overrideprotected String getKey(NginxCommonConfigParam configParam, ChannelHandlerContext ctx, Object object, NginxRequestDispatchContext context) {return "proxy_hide_header";}}
proxy_cookie_flags 指令
支持哪些?
在 Nginx 中,proxy_cookie_flags 指令用于设置从代理服务器返回给客户端的 Set-Cookie 头中特定 cookie 的属性标志。主要支持的配置选项包括:
HttpOnly:将
HttpOnly标志添加到 cookie,使得 JavaScript 无法通过document.cookie访问该 cookie。proxy_cookie_flags <cookie_name> HttpOnly;Secure:将
Secure标志添加到 cookie,仅在通过 HTTPS 协议发送时才会发送该 cookie。proxy_cookie_flags <cookie_name> Secure;SameSite:设置
SameSite标志,限制浏览器仅在同站点请求时发送该 cookie,有助于防止跨站点请求伪造(CSRF)攻击。proxy_cookie_flags <cookie_name> SameSite=Strict;支持的
SameSite值包括Strict、Lax和None。Max-Age:设置
Max-Age属性,指定 cookie 的过期时间(秒)。通常用于设置持久化 cookie 的过期时间。proxy_cookie_flags <cookie_name> Max-Age=3600;Expires:设置
Expires属性,指定 cookie 的过期时间点。通常以 GMT 格式的日期字符串指定。proxy_cookie_flags <cookie_name> Expires=Wed, 21 Oct 2026 07:28:00 GMT;Domain:设置
Domain属性,指定可接受该 cookie 的域名范围。通过proxy_cookie_domain指令更常用地配置。proxy_cookie_flags <cookie_name> Domain=example.com;Path:设置
Path属性,指定该 cookie 的路径范围。proxy_cookie_flags <cookie_name> Path=/;
示例
以下是一些示例,展示如何使用 proxy_cookie_flags 指令设置不同的 cookie 标志:
server {listen 80;server_name example.com;location / {# 添加 HttpOnly 和 Secure 标志proxy_cookie_flags session_cookie HttpOnly Secure;# 设置 SameSite 标志为 Strictproxy_cookie_flags mycookie SameSite=Strict;# 设置 Max-Age 为 1 小时proxy_cookie_flags persistent_cookie Max-Age=3600;# 设置 Expires 属性proxy_cookie_flags old_cookie Expires=Wed, 21 Oct 2026 07:28:00 GMT;# 设置 Domain 属性proxy_cookie_flags global_cookie Domain=example.com;# 设置 Path 属性proxy_cookie_flags local_cookie Path=/subpath;proxy_pass http://backend;}
}
通过这些配置,您可以灵活地控制从代理服务器返回的 Set-Cookie 头中各个 cookie 的属性,以满足安全需求和业务逻辑。
java 核心实现
public void doBeforeWrite(NginxCommonConfigParam configParam, ChannelHandlerContext ctx, Object object, NginxRequestDispatchContext context) {if(!(object instanceof HttpResponse)) {return;}List<String> values = configParam.getValues();if(CollectionUtil.isEmpty(values) || values.size() < 2) {return;}HttpResponse response = (HttpResponse) object;HttpHeaders headers = response.headers();String cookieHeader = headers.get(HttpHeaderNames.COOKIE);final String cookieName = values.get(0);if (cookieHeader != null) {Set<Cookie> cookies = ServerCookieDecoder.STRICT.decode(cookieHeader);Set<Cookie> modifiedCookies = cookies.stream().map(cookie -> {// 相同的名字if (cookieName.equals(cookie.name())) {// HttpOnly Securefor(int i = 1; i < values.size(); i++) {String value = values.get(i);if("HttpOnly".equals(value)) {cookie.setHttpOnly(true);}if("Secure".equals(value)) {cookie.setSecure(true);}// 拆分if(!value.contains("=")) {return cookie;}String[] items = value.split("=");String itemKey = items[0];String itemVal = items[1];// if("SameSite".equals(itemKey) && "Strict".equals(itemVal)) {
// }if("Max-Age".equals(itemKey)) {cookie.setMaxAge(Long.parseLong(itemVal));}if("Expires".equals(itemKey)) {Date expireDate = calcDate(itemVal);long maxAge = expireDate.getTime() - System.currentTimeMillis();cookie.setMaxAge(maxAge);}if("Domain".equals(itemKey)) {cookie.setDomain(itemVal);}if("Path".equals(itemKey)) {cookie.setPath(itemVal);}}}return cookie;}).collect(Collectors.toSet());List<String> encodedCookies = ServerCookieEncoder.STRICT.encode(modifiedCookies);headers.set(HttpHeaderNames.COOKIE, encodedCookies);}logger.info(">>>>>>>>>>>> doBeforeWrite proxy_cookie_flags values={}", values);}
nginx proxy_cookie_path 指令
介绍
在 Nginx 中,proxy_cookie_path 指令用于修改传递到后端服务器的 HTTP 请求中的 Cookie 的路径。
这个指令通常在反向代理服务器配置中使用,用于调整传递给后端服务器的 Cookie 的路径信息,以适应后端服务器的预期路径结构。
语法和用法
语法:
proxy_cookie_path regex path;
参数解释:
regex:一个正则表达式,用于匹配要修改的 Cookie 的路径。path:要替换成的路径。
示例
假设有如下配置:
location /app/ {proxy_pass http://backend.example.com;proxy_cookie_path ~*^/app(.*) $1;
}
在这个示例中:
proxy_cookie_path指令配合proxy_pass使用,表示将从客户端接收的带有路径/app/的 Cookie 的路径信息去除/app部分后再传递给后端服务器。
例如,如果客户端发送的 Cookie 路径是 /app/session, Nginx 将修改为 /session 后传递给后端服务器。
注意事项
- 使用
proxy_cookie_path时,确保理解你的后端服务器期望接收的 Cookie 路径格式,以便正确设置正则表达式和路径。 - 正则表达式必须能够正确匹配客户端发送的 Cookie 路径。
- 这个指令通常用于调整不同路径的代理请求,以便与后端服务器的预期路径结构匹配。
java 核心实现
public void doBeforeDispatch(NginxCommonConfigParam configParam, NginxRequestDispatchContext context) {List<String> values = configParam.getValues();if(CollectionUtil.isEmpty(values) || values.size() < 2) {throw new Nginx4jException("proxy_cookie_path 必须包含2个参数");}FullHttpRequest request = context.getRequest();// 原始String regex = values.get(0);String path = values.get(1);HttpHeaders headers = request.headers();String cookieHeader = headers.get(HttpHeaderNames.COOKIE);if (cookieHeader != null) {String modifiedCookieHeader = cookieHeader.replaceAll(regex, path);headers.set(HttpHeaderNames.COOKIE, modifiedCookieHeader);}logger.info(">>>>>>>>>>>> doBeforeDispatch proxy_cookie_path replace regex={} => path={}", regex, path);
}
小结
对于 cookie 的处理,让我们的请求可以更加强大灵活。
proxy_cookie_domain: 设置后端服务器响应的 Cookie 中的域名。proxy_cookie_flags: 设置后端服务器响应的 Cookie 的标志位。proxy_cookie_path: 设置后端服务器响应的 Cookie 的路径。
我是老马,期待与你的下次重逢。
开源地址
为了便于大家学习,已经将 nginx 开源
https://github.com/houbb/nginx4j
相关文章:
从零手写实现 nginx-23-nginx 对于 cookie 的操作
前言 大家好,我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的,可以参考我的另一个项目: 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …...
Python语言例题集(015)
#!/usr/bin/python3 #使用列表模仿队列的操作。 class Queue(): def init(self): self.queue[] def enqueue(self,data):self.queue.insert(0,data)def dequeue(self):if len(self.queue):return self.queue.pop()return "队列是空的"qQueue() q.enqueue(‘Grape’…...
Halcon C++ XLD 数据写入图片
1. xld转换为Region 生成与调用函数 gen_cross_contour_xld (CrossXld, Rows, UpdateCols, 6, 0) get_xld_region (CrossXld, xldRegions)函数实现 get_xld_region * 计算XLD个数 count_obj (BaseXld, Number) * 生成空的区域(结果) gen_empty_region…...
一文入门vim
先来波快问快答。 第一个问题,vim是什么? vim就是一文本编辑器。 第二个问题,我们为什么要使用vim? 好像在终端中可选择使用的文本编辑器也不多(其他有,但是相对而言vim用的比较广泛) 第三…...
植物ATAC-seq文献集锦(三)——果实发育篇
ATAC-seq在植物研究领域的应用我们已经介绍2期了,本期我们聚焦ATAC-seq技术在果实发育方向的应用案例。 植物ATAC-seq文献集锦(一)——基因组篇 植物ATAC-seq文献集锦(二)——生长发育篇 文献一:Ident…...
在自己的电脑上搭建我的世界Java版服务器
很多朋友,喜欢玩Minecraft,也希望搭建一个服务器,用于和小伙伴联机; 并且,拥有服务器后,即使所有玩家都下线,“世界”依旧在运行,玩家可以随时参与其中,说不定一上线&am…...
1.PyQt6库和工具库QTDesigner安装
1.安装PyQT6和pyqt6-tools 1. PyQt6库是PyQt的开发库 2.pyqt6-tool时QTDesigner设计器工具支持库 pip install PyQt6 pip install pyqt6-tools 2.在Pycharm中配置外部工具QTDesigner和PYGIC 配置外部工具QTDesigner 1. QTDesigner是QT界面设计器 2.打开Pycharm->Settin…...
Hbase搭建教程
Hbase搭建教程 期待您的关注 ☀小白的Hbase学习笔记 目录 Hbase搭建教程 1.上传hbase的jar包并解压 2.重新登录 3.启动zookeeper 4.配置环境变量 5.关闭ZK的默认配置 6.修改hbase-site.xml文件 7.修改regionservers文件 8.将配置好的文件分发给其它节点 9.配置环境变量…...
利用three-csg-ts对做物体交互式挖洞
默认物体均为居中,如果指定位置没有发生偏移,可能是因为在执行布尔操作之前没有正确设置变换。确保在进行布尔运算之前应用所有必要的变换。以下是经过修正的完整代码示例,它会确保圆柱正确旋转并与盒子进行 CSG 操作。 安装依赖 首先&…...
腾讯云对象存储不绑定自定义备案域名不给下载应该如何处理?
从2024年1月1日起,腾讯云对象存储(COS)将实施新政策:新创建的存储桶不再支持使用path-style域名(即存储桶绝对路径)。此外,使用默认域名访问的新存储桶将不再支持任意类型文件的预览,…...
C 语言实例 - 输出数组
使用 for 循环输出数组 #include <stdio.h>int main() {int array[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};int loop;for(loop 0; loop < 10; loop)printf("%d ", array[loop]);return 0; }输出结果为: 1 2 3 4 5 6 7 8 9 0使用 for 循环逆向输…...
回溯算法练习题(2024/6/10)
1组合 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2: 输入:n …...
机器学习--线性模型和非线性模型的区别?哪些模型是线性模型,哪些模型是非线性模型?
文章目录 引言线性模型和非线性模型的区别线性模型非线性模型 总结线性模型非线性模型 引言 在机器学习和统计学领域,模型的选择直接影响到预测的准确性和计算的效率。根据输入特征与输出变量之间关系的复杂程度,模型可以分为线性模型和非线性模型。线性…...
[linux] Qwen2Tokenizer报错 transformers版本问题
上午没问题,下午pull了新代码,就有了报错。。 发现是transformers版本问题。但。。其实我都默认安的是最新版本。。 也许这就是人生吧。。 报错: File "/Pai-Megatron-Patch/megatron_patch/tokenizer/__init__.py", line 213…...
算法刷题笔记 单链表(C++实现)
文章目录 题目描述基本思路实现代码 题目描述 实现一个单链表,链表初始为空,支持三种操作: 向链表头插入一个数;删除第 k个插入的数后面的一个数;在第 k个插入的数后插入一个数。 现在要对该链表进行M次操作&#x…...
Oracle 排查慢SQL
Oracle 排查慢SQL select * from v s q l a r e a w h e r e r o w n u m < 10 ; s e l e c t ∗ f r o m v sqlarea where rownum<10; select * from v sqlareawhererownum<10;select∗fromvsql where rownum<10; select * from dba_hist_sqltext where rownum<…...
java技术专家面试指南80问【java学习+面试宝典】(七)
Dubbo需要 Web 容器吗? 不需要,如果硬要用 Web 容器,只会增加复杂性,也浪费资源。 PrintStream、BufferedWriter、PrintWriter的比较? PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应…...
4机器学习期末复习
在机器学习中,数据清洗与转换包括哪些内容? 对数据进行初步的预处理,需要将其转换为一种适合机器学习模型的表示形式对许多模型类型来说,这种表示就是包含数值数据的向量或者矩阵: 1)将类别数据编码成为对…...
chatgpt: int t[] int *t 区别
在C语言中,int t[]和int *t虽然在某些情况下可以相互替换,但它们有一些关键的区别。这些区别主要体现在声明的语义、内存分配方式和使用场景上。以下是详细的解释: ### 1. int t[] #### 语义: - int t[]声明了一个数组,t是一个数…...
网络安全技术实验六 入侵检测技术实践
一、实验目的和要求 理解基于网络的入侵检测系统的基本原理,掌握snort IDS工作机理; 学习应用snort三种方式工作;熟练编写snort规则; 完成snort数据包记录、日志查看、字符串匹配、ARP欺骗攻击检测、端口扫描工具检测等功能。 …...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
