vue 项目优雅的对 url 参数加密

Vue3实战:如何优雅地从静态页面URL获取参数(附完整代码) 本文详细介绍了在Vue3项目中优雅地从静态页面URL获取参数的三种工程化解决方案,包括基础解析方案、Vue Router集成方案和状态管理集成。通过URLSearchParams API和Vue Router的原生支持,开发者可以高效处理URL参数,提升代码可维护性。文章还提供了生产环境最佳实践和高级应用场景,如类型安全处理、参数验证与转换等。 阅读详情

实现方案:stringifyQuery 和 parseQuery

近期因为公司内部的安全检查,说我们现在的系统中参数是明文的,包括给后端请求的参数和前端页面跳转携带的参数,因为是公司内部使用的系统,在安全性方面的设计考虑确实不够充分

对于参数的加密和解密很好实现,直接采用常用的 AES 算法,前后端定义好通用的密钥和加解密方式就好,前端加解密这里主要使用到 crypto-js 这个工具包,再通过一个类简单封装一下加解密的算法即可

// src\utils\cipher.ts
import { encrypt, decrypt } from 'crypto-js/aes'
import { parse } from 'crypto-js/enc-utf8'
import pkcs7 from 'crypto-js/pad-pkcs7'
import ECB from 'crypto-js/mode-ecb'
import UTF8 from 'crypto-js/enc-utf8'

// 注意 key 和 iv 至少都需要 16 位
const AES_KEY = '1111111111000000'
const AES_IV = '0000001111111111'

export class AesEncryption {private keyprivate ivconstructor(key = AES_KEY, iv = AES_IV) {this.key = parse(key)this.iv = parse(iv)}get getOptions() {return {mode: ECB,padding: pkcs7,iv: this.iv,}}encryptByAES(text: string) {return encrypt(text, this.key, this.getOptions).toString()}decryptByAES(text: string) {return decrypt(text, this.key, this.getOptions).toString(UTF8)}
} 

对于前端页面间跳转携带参数,我们项目使用的都是 vue-router 的 query 来携带参数,但是有那么多页面跳转的地方,不可能都手动添加加解密方法处理吧,工作量大不说,万一漏改一个就可能导致整个页面无法加载了,这锅可不能背

首先想到的方法是在路由守卫 beforeEach 中对参数进行加密,然后在 afterEach 守卫中对参数进行解密,但是这个想法在 beforeEach 中加密就无法实现。原因是 beforeEach(to, from, next) 的第三个参数 next 函数中,如果参数是路由对象,会导致跳转死循环

接下来经过几个小时百思不得其解(摸鱼)之后,最终在 API 参考 | Vue Router (vuejs.org) 找到这样两个 API:stringifyQuery 和 parseQuery,官网的定义如下

stringifyQuery:对查询对象进行字符串化的自定义实现。不应该在前面加上 ?。应该正确编码查询键和值

parseQuery:用于解析查询的自定义实现。必须解码查询键和值

比如,官网建议如果想使用 qs 包来解析查询,可以这样配置

import qs from 'qs'

createRouter({// 其他配置...parseQuery: qs.parse,stringifyQuery: qs.stringify,
}) 

现在最终的解决方案就很明确了,自定义两个参数加密、解密的方法,然后在 createRouter 中添加到 stringifyQuery 和 parseQuery 这两个方法就可以了,下面是详细代码

// src/router/helper/query.js
import { isArray, isNull, isUndefined } from 'lodash-es'
import { AesEncryption } from '@/utils/cipher'
import type {LocationQuery,LocationQueryRaw,LocationQueryValue,
} from 'vue-router'

const aes = new AesEncryption()

/**
 *
 * @description 解密:反序列化字符串参数
 */
export function stringifyQuery(obj: LocationQueryRaw): string {if (!obj) return ''const result = Object.keys(obj).map((key) => {const value = obj[key]if (isUndefined(value)) return ''if (isNull(value)) return keyif (isArray(value)) {const resArray: string[] = []value.forEach((item) => {if (isUndefined(item)) returnif (isNull(item)) {resArray.push(key)} else {resArray.push(key + '=' + item)}})return resArray.join('&')}return `${key}=${value}`}).filter((x) => x.length > 0).join('&')return result ? `?${aes.encryptByAES(result)}` : ''
}

/**
 *
 * @description 解密:反序列化字符串参数
 */
export function parseQuery(query: string): LocationQuery {const res: LocationQuery = {}query = query.trim().replace(/^(\?|#|&)/, '')if (!query) return resquery = aes.decryptByAES(query)query.split('&').forEach((param) => {const parts = param.replace(/\+/g, ' ').split('=')const key = parts.shift()const val = parts.length > 0 ? parts.join('=') : nullif (!isUndefined(key)) {if (isUndefined(res[key])) {res[key] = val} else if (isArray(res[key])) {;(res[key] as LocationQueryValue[]).push(val)} else {res[key] = [res[key] as LocationQueryValue, val]}}})return res
}

// src/router/index.js
// 创建路由使用加解密方法
import { parseQuery, stringifyQuery } from './helper/query'

export const router = createRouter({// 创建一个 hash 历史记录。history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH),routes: basicRoutes,scrollBehavior: () => ({ left: 0, top: 0 }),stringifyQuery, // 序列化query参数parseQuery, // 反序列化query参数
}) 

加密的效果如下,我也在 github 上传了加密方式的 demo,可以直接下载体验一下

更进一步:相关实现原理

在实现完这两个功能之后,我突然想翻一下 Vue Router 的源码,看一下 stringifyQuery 和 parseQuery 的实现原理,避免以后遇到类似的问题再抓瞎

打开 Vue Router@4的源码,整个项目是用 pnpm 管理 monorepo 的方式组织,通过 rollup.config.js 中定义的 input 入口可以知道,所有的方法都通过 packages/router/src/index.ts 导出

首先先看初始化路由实例的 createRouter 方法,这个方法主要做了这么几件事

1.通过 createRouterMatcher 方法,根据路由配置列表创建 matcher,返回 5 个操作 matcher 方法。matcher 可以理解为路由页面匹配器,包含路由所有信息和 crud 操作方法
2.定义三个路由守卫:beforeEach、beforeResolve、afterEach
3.声明当前路由 currentRoute,对 url 参数 paramas 进行编码处理
4.添加路由的各种操作方法,最后返回一个 router 对象

一个简化版本的 createRouter 方法如下所示,前文使用到的 stringifyQuery 和 parseQuery 都是在这个方法中加载

export function createRouter(options: RouterOptions): Router {// 创建路由匹配器 matcherconst matcher = createRouterMatcher(options.routes, options)// ! 使用到的 stringifyQuery 和 parseQueryconst parseQuery = options.parseQuery || originalParseQueryconst stringifyQuery = options.stringifyQuery || originalStringifyQuery// ! 路由守卫定义const beforeGuards = useCallbacks<NavigationGuardWithThis<undefined>>()const beforeResolveGuards = useCallbacks<NavigationGuardWithThis<undefined>>()const afterGuards = useCallbacks<NavigationHookAfter>()// 声明当前路由const currentRoute = shallowRef<RouteLocationNormalizedLoaded>(START_LOCATION_NORMALIZED)let pendingLocation: RouteLocation = START_LOCATION_NORMALIZED// leave the scrollRestoration if no scrollBehavior is providedif (isBrowser && options.scrollBehavior && 'scrollRestoration' in history) {history.scrollRestoration = 'manual'}// url 参数进行编码处理const normalizeParams = applyToParams.bind(null,(paramValue) => '' + paramValue)const encodeParams = applyToParams.bind(null, encodeParam)const decodeParams: (params: RouteParams | undefined) => RouteParams =applyToParams.bind(null, decode) } 

从创建路由实例来看, stringifyQuery 和 parseQuery 两个参数如果没有自定义传入的情况下,会使用 vue-router 默认的解析函数

默认的 stringifyQuery 函数用于把参数由对象形式转换为字符串连接形式,主要流程

1.循环参数 query 对象
2.特殊处理参数为 null 的情况,参数值为 null 的情况会拼接在 url 链接中但是没有值,而参数值为 undefined 则会直接忽略
3.将对象转化为数组,并且对每个对象的值进行 encoded 处理
4.将数组拼接为字符串参数

// vue-router 默认的序列化 query 参数的函数
export function stringifyQuery(query: LocationQueryRaw): string {let search = ''for (let key in query) {const value = query[key]key = encodeQueryKey(key)// 处理参数为 null 的情况if (value == null) {if (value !== undefined) {search += (search.length ? '&' : '') + key}continue}// 将参数处理为数组,便于后续统一遍历处理const values: LocationQueryValueRaw[] = isArray(value)? value.map(v => v && encodeQueryValue(v)): [value && encodeQueryValue(value)]values.forEach(value => {// 跳过参数为 undefined 的情况,只拼接有值的参数if (value !== undefined) {search += (search.length ? '&' : '') + keyif (value != null) search += '=' + value}})}return search
}

// 示例参数,如下参数会被转换为:name=wujieli&age=12&address
// query: {
// id: undefined,
// name: 'wujieli',
// age: 12,
// address: null,
// }, 

默认的 parseQuery 函数用来将字符串参数解析为对象,主要流程

1.排除空字符串和字符串前的 “?”
2.对字符串用 “&” 分割,遍历分割后的数组
3.根据 “=” 截取参数的 key 和 value,并对 key 和 value 做 decode 处理
4.处理 key 重复存在的情况,如果 key 对应 value 是数组,就把 value 添加进数组中,否则就覆盖前一个 value

 // vue-router 默认的序列化 query 参数的函数
export function parseQuery(search: string): LocationQuery {const query: LocationQuery = {}// 因为要对字符串进行 split('&') 操作,所以优先排除空字符串if (search === '' || search === '?') return query// 排除解析参数前的 ?const hasLeadingIM = search[0] === '?'const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&')for (let i = 0; i < searchParams.length; ++i) {// 根据 = 截取参数的 key 和 value,并做 decode 处理const searchParam = searchParams[i].replace(PLUS_RE, ' ')const eqPos = searchParam.indexOf('=')const key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos))const value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1))// 处理 key 重复存在的情况if (key in query) {// an extra variable for ts typeslet currentValue = query[key]if (!isArray(currentValue)) {currentValue = query[key] = [currentValue]}// we force the modification;(currentValue as LocationQueryValue[]).push(value)} else {query[key] = value}}return query
} 

stringifyQuery 这个方法用在创建 router 实例时提供的 resolve 方法中用来生成 url,parseQuery 方法主要用在 router.push、router.replace 等方法中解析 url 携带的参数

// stringifyQuery 方法的使用
function resolve( rawLocation: Readonly<RouteLocationRaw>,
 currentLocation?: RouteLocationNormalizedLoaded ): RouteLocation & { href: string } {// ...// 链接的完整 path,包括路由 path 和后面的完整参数const fullPath = stringifyURL(stringifyQuery,assign({}, rawLocation, {hash: encodeHash(hash),path: matchedRoute.path,}))
}

// parseQuery 方法会封装在 locationAsObject 方法中使用
function locationAsObject( to: RouteLocationRaw | RouteLocationNormalized ): Exclude<RouteLocationRaw, string> | RouteLocationNormalized {return typeof to === 'string'? parseURL(parseQuery, to, currentRoute.value.path): assign({}, to)
} 

以上就是 stringifyQuery 和 parseQuery 两个方法的实现原理,可以看到源码中对于参数的加密解密考虑的处理是更多的,其实也可以把两个方法的源码拷贝出来,加上加密、解密的方法然后覆盖源码即可

前端加密与解密的几种方式 MD5是一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。MD5.JS是通过前台js加密的方式对密码等私密信息进行加密的工具。这个主要是使用JS函数的escape()和unescape(),分别是编码和解码字符串。escape采用ISO Latin字符集对指定的字符串进行编码。 阅读详情

相关推荐

Vue2项目集成SM4国密算法实现前端请求加密的完整实践

在前端开发中,数据传输安全是构建可靠应用的基础。HTTPS协议确保了传输层的安全,但在应用层,敏感数据仍需额外保护以防止服务器端或中间环节的明文泄露。前端加密技术通过在客户端对数据进行加密处理,实现端到端的安全保障,有效提升了数据泄露的门槛。其核心原理是利用加密算法对明文进行转换,只有持有正确密钥的接收方才能解密。这项技术在金融、政务、电商等对数据安全有严格合规要求的场景中具有重要价值。本文聚焦于在Vue2项目中,通过axios拦截器与SM4国密算法,实现了一套包含动态密钥管理与白名单机制的前端请求加密方案

weixin_33768481的博客 399

base64解码与转码

let Base64 = { encode(str) { // first we use encodeURIComponent to get percent-encoded UTF-8, // then we convert the percent encodings into raw bytes which // can be fed into bt...

weixin_43893437的博客 2970

Vue 3项目中AES加密实战:从Crypto-js集成到前后端安全通信

数据安全是Web应用开发的核心议题,尤其在涉及用户敏感信息传输时。AES(高级加密标准)作为一种对称加密算法,通过将明文数据与密钥进行多轮替换和置换运算,生成不可读的密文,其安全性已得到全球广泛验证。在工程实践中,前端加密的核心价值并非替代HTTPS,而是在传输层安全之上,为应用层数据提供额外的保护,确保数据在服务器日志、浏览器开发者工具等环节不以明文暴露。这能有效防范旁路攻击和部分中间人攻击,在登录、支付等敏感场景中尤为重要。本文以Vue 3项目为例,详细阐述了如何集成成熟的Crypto-js库,封装可复

cuemes08808的博客 321

vue AES加密(URLEncode加密)

vue AES加密(URLEncode加密)

m0_58352785的博客 4108

若依Vue3集成jsencrypt实现前端密码加密传输实战指南

在Web应用开发中,数据传输安全是至关重要的技术环节,尤其是在登录、支付等敏感操作场景。RSA非对称加密作为一种成熟的安全方案,通过公钥加密、私钥解密的原理,有效解决了网络传输过程中敏感信息(如密码)的明文暴露风险。其技术价值在于,即便请求被截获,攻击者也无法在没有私钥的情况下破解密文,从而构建了从客户端到服务器的单向安全通道。这一技术广泛应用于各类后台管理系统、SaaS平台及金融应用,确保用户凭证在传输过程中的机密性。本文以若依Vue3后台管理系统为背景,深入探讨如何将jsencrypt库与现有技术栈(如

culiao6493的博客 481

Vue3前端RSA加密密码:从原理到工程实践的安全传输方案

在Web应用开发中,数据传输安全是保障用户隐私和系统安全的核心环节。非对称加密技术通过公钥加密、私钥解密的机制,解决了密钥分发的安全难题,为前端到后端的数据传输提供了基础安全保障。RSA作为经典的非对称加密算法,其技术价值在于能够在不暴露私钥的前提下,实现数据的加密传输,有效防止中间人攻击和敏感信息泄露。这一技术广泛应用于用户登录、注册、支付等涉及密码和敏感数据的传输场景。本文聚焦于Vue3框架下的RSA加密实现,详细解析如何结合jsencrypt库和Composition API,构建高效、安全的前端加密

aoanping0730的博客 482

url中的参数加密

有时候我们需要在地址栏传输一些信息,比如查询数据的时候,传一个参数location.href = "/admin/extract?name="+"参数aaa"’但是我们直接这样传输会有一些问题,我们通常会进行加密,下面介绍一个很简单的加密方式,先把文档地址放上crypto-js 我们首先在页面中引入js,<script type="text/javascript" src="/js/tools/c

suxiao的博客 2万+

URL传参加密

URL传递参数的一种加密方法,让您的参数不在明文传输

Spring Cloud Gateway 数字签名、URL动态加密这样设计真优雅

A将数据发送到B之后,由于数据使用的是B的公钥加密,B可以用私钥解密之后,得到A发送消息的原本内容,然后,B可以使用A的公钥对额外的数字签名进行校验,因为它假设这个数据是A发送的,那么用A的公钥就应该可以解密成功,所以如果数据解密成功之后与A发送的原始消息经过一样的Hash运算之后相等,那么说明没有被篡改,而如果不一致,那么就说明被篡改了。因为第三方是不知道A的私钥信息的,所以他是用自己的私钥去加密,得到的hash会与A进行hash之后的值不同,从而判断数据被篡改了。服务器用自己的私钥解密得到对称密钥。

m0_73735578的博客 1276

智能变电站协议系列-1、GOOSE、SV、MMS协议简介及GOOSE示例运行问题(IEC61850)

目前有一个新的研究,关于电网使用的GOOSE、SV、MMS协议,并使用相关库来做一下测试。由于goose、sv、mms等都属于IEC61850,因此,需要对IEC61850相关内容有一些了解,都是国际标准,属于电气自动化的一部分,对于自动化或者电气相关领域有接触的专业应该或多或少有一些了解。IEC61850目标是用于变电站自动化、分布式能源、水力和天然气发电厂、风力发电厂、电动汽车作为分布式能源等领域,目前似乎在变电站自动化方面的推广和使用更加广泛。

逍遥游的博客 2万+

【深度剖析】三一重工的数字化转型(中篇)

三一重工在数字化转型方面取得了提高效率、降低成本、加强研发创新和改善内控管理等多方面的成效。本研究旨在通过对三一重工数字化转型的深入分析,引导企业思考在第四次工业革命与第三次能源革命交汇的超级技术窗口期,如何进一步把握发展机遇,并为同行业其他企业提供探索性的建议。作为装备制造行业的佼佼者,三一重工的数字化转型受到了业界的广泛关注。作为行业内首批接触并实践数字化转型的企业之一,三一重工的转型经验不仅成功,而且积累了丰富的理论与实践,为其他制造业企业的数字化转型提供了可借鉴的范例。

领信卓越的博客 2306

Spring Cloud Gateway 数字签名、URL动态加密这样设计真优雅!

A将数据发送到B之后,由于数据使用的是B的公钥加密,B可以用私钥解密之后,得到A发送消息的原本内容,然后,B可以使用A的公钥对额外的数字签名进行校验,因为它假设这个数据是A发送的,那么用A的公钥就应该可以解密成功,所以如果数据解密成功之后与A发送的原始消息经过一样的Hash运算之后相等,那么说明没有被篡改,而如果不一致,那么就说明被篡改了。因为第三方是不知道A的私钥信息的,所以他是用自己的私钥去加密,得到的hash会与A进行hash之后的值不同,从而判断数据被篡改了。服务器用自己的私钥解密得到对称密钥。

weixin_44421461的博客 82

螺丝锁付系统软件设计 C# Winform

视觉螺丝锁付系统软件设计 C# Winform ,这是其中通信子模块设计

weixin_42522973的博客 340

autojs连模拟器_autojs-vue

AutoJs-Vue 特性帮助开发者,快速生产友好的AutoJS程序1. 全面支持(信息量很大):AutoJS:全接口支持VUE:著名的渐进式JavaScript框架(傻瓜->高手),color-Ui:优雅的前端视觉交互设计(默认内置,也可以换成其他UI框架)HTML5plus:让JS拥有与App一样的能力标准组件,API,框架:增强APP的手机系统访问功能插件社区,云开发,uni开发者社群...

weixin_42168902的博客 3916

79-Halcon-- visualize_object_model_3d 函数功能(交互式3D可视化)

该算子是连接3D数据与决策者的关键可视化桥梁,通过其独特的交互能力和高质量的渲染效果,将复杂的3D信息转化为直观的可视内容,大幅提升工程决策效率和质量。操作符,不仅能在窗口中渲染3D对象,还支持多种交互操作,适用于调试、展示和交互分析场景。本解析将全面探讨其参数功能及工业级应用方案。+几何类型: PointCloud/ TriMesh/CAD。+法线属性: [NX,NY,NZ]+附加数据: Attributes。是Halcon中功能强大的。+顶点属性: [X,Y,Z]+颜色属性: [R,G,B]

weixin_45590420的博客 1205

详解Linux下使用vscode编译运行和调试C/C++

本教程将具体详解使用Visual Studio Code在Linux环境下使用C/C++方法。 GCC C++ 编译器 (g++) 和 GDB 调试器的方法。 GCC是GNU 编译器集合; GDB 是 GNU 调试器。 1.先决条件 安装Visual Studio Code. 安装C++拓展插件。点击在vscode界面最左侧的Extensions图标(打开快捷键:ctrl+shift+X),搜索“C/C++”,点击进行安装。 确保已安装gcc. 一般ubuntu系统会预装gcc.在终端窗口中输入如下命令

休的博客 6240

Vue项目,异步队列解决双令牌请求

使用双令牌的初衷 为了方便分布式部署,平台所有接口都允许跨域访问,但为了防止恶意请求,需要设置请求头、令牌等; 有一部分页面不需要登录就可以查看,接口请求带一个静态令牌,有一部分需要有登录权限才能查看,就需要动态令牌。 静态令牌:利用RSA加密与后台约定一个publicKey生成一个加密串,请求接口换取静态令牌; 动态令牌:利用静态令牌请求接口换取动态令牌 复制代码 踩坑点 1.请求时怎么区分该接...

weixin_34343308的博客 773

如何使用 Conda 安装 Qiskit(详细教程)

本文介绍了使用conda安装Qiskit量子计算工具包的完整流程。首先创建Python 3.10的conda虚拟环境(qiskit_env),然后安装Qiskit核心包及可视化组件(注意Mac用户的安装命令差异)。接着注册IPython内核并测试环境,通过量子电路创建与可视化演示验证安装成功。该教程为量子计算开发提供了简洁的环境配置指南,适合研究者和开发者快速搭建Qiskit开发环境。

猿小白的博客 564

Vue项目中iframe嵌入页面实现免登录的完整指南

监听器放在App.vue的created生命周期中验证消息来源(origin)添加时间戳防止重放攻击设置合理的token有效期在beforeDestroy中移除监听器处理不同源场景(token交换)避免localStorage key冲突开发环境:可以先用URL传参快速验证功能,但上线前一定要改成postMessage调试技巧:在控制台打印消息收发日志,方便排查问题错误处理:做好异常处理,当token失效时优雅降级到登录页。

duduanwang的博客 892

《Python基础教程》内容总览篇(持续更新中)

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为优快云博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理解,而且能够帮助新手快速入门。个人精心开设的《Python基础课程》专栏订阅量接近900,帮助不少同学解决了Bug。

weixin_43178406的博客 35万+

42、使用mmrotate中k3det进行旋转目标检测,并进行mnn部署和ncnn部署

基本思想:仍然是身份证分割,并进行ncnn和mnn的c++的部署开发

sxj731533730 5706

【GitHub项目推荐--Laravel:优雅的PHP Web应用框架】

​Laravel​ 是一个具有表达力、优雅语法的PHP Web应用程序框架。它旨在通过简化常见任务(如路由、认证、会话、缓存等)来减轻开发痛苦,使开发过程变得愉快和富有创造性。Laravel易于访问、功能强大,并提供构建大型、健壮应用程序所需的工具。🔗 ​GitHub地址🚀 ​核心价值​:PHP框架 · Web开发 · 优雅语法 · 开发体验 · 开源免费​项目背景​:​Web开发​:应对现代Web开发需求​开发体验​:注重开发者体验​PHP生态​:PHP生态系统发展​企业应用。

j8267643的博客 1070

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Vue 项目优雅封装 Axios:告别重复代码,统一接口管理

本文详细介绍了在Vue项目中封装axios的最佳实践。通过创建axios实例、配置请求/响应拦截器,实现统一管理接口、自动添加token、错误处理等功能。建议按业务模块拆分接口文件,并通过环境变量区分开发/生产环境。进阶优化包括请求取消和重试机制。这种封装方式能显著提升代码复用性、可维护性和开发效率,使接口调用更加规范优雅,降低后期维护成本。

qq_38305872的博客 316

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【JavaScript】获取指定的url后端返回的header头里的数据

一开始准备直接过滤所有的拦截信息然后把需要的url信息存到本地,可以直接过滤需要的url然后修改返回值。在调取接口时直接取用。想要获取指定的url的header头,只能在拦截器过滤。再通过再次在页面请求接口保存header头。

Hypnotic0624的博客 2023

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: Vue 模板编译原理
下一篇: vulnhub_内网渗透测试的记录——网络安全
李小珣1926
博客等级 码龄4年 0粉丝 9原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值