http通讯及浏览器中的HTML编码、URL编码、base64编码
http通讯及浏览器中的HTML编码、URL编码、base64编码及转义
目录
http通讯及浏览器中的HTML编码、URL编码、base64编码及转义
1、html编码的特殊字符
1.1、HTML 实体
1.2、HTML字符实体,数据的表达
2、URL编码的特殊字符
2.1、URL支持的字符
2.2、ASCII字符编码表
3、Base64编码的特殊字符
3.1、base64在http和html中有许多使用场景
3.2、base64字符编码表
3.3、base64字节规则及编码步骤
1、html编码的特殊字符
HTML encoding character
HTML 和 XHTML 用标准的 7 比特 ASCII 代码在网络上传输数据。
1.1、HTML 实体
HTML语言 中的“保留字”,即某些预留字符。
比如不能在除“元素”意外的位置,使用小于号(<)和大于号(>),浏览器会误解为它们是标签。
若有需要让浏览器正确地显示预留字符,我们必须在 HTML 源代码中使用字符实体(character entities)。
1.2、HTML字符实体,数据的表达
1、&号 “加” 特殊字符的“约定实体名称” “加” ;号,比如符号 < ,表达为 <
注意,实体名称大小写敏感。或者
2、&号 “加” # “加” 特殊字符的ASCII码 “加” ;号,比如符号 < ,表达为 <
1、&号 “加” 特殊字符的“约定实体名称” “加” ;号,比如符号 < ,表达为 <
注意,实体名称大小写敏感。或者
2、&号 “加” # “加” 特殊字符的ASCII码 “加” ;号,比如符号 < ,表达为 <
html保留字的字符实体表
2、URL编码的特殊字符
URL encoding character
2.1、URL支持的字符
由于URL只支持英文字母、数字、横杠、下划线、句点、波浪线,若要表示其他字符则需要编码。
例如百分号、中文。
由于百分号也需要编码,会出现某些绕过问题。
①、URL编码基于ASCII码
- URL中无特殊字符 全是ASCII可显示字符
https://.cpuofbs./rest/postdata?A=abc&B=123
https://.cpuofbs./rest/postdata?A=abc&B=123
- URL中包含特殊字符 空格 、
https://.cpuofbs./rest/postdata?A= abc&B、=123
https://.cpuofbs./rest/postdata?A=%20abc&B%E3%80%81=123
- URL中包含特殊字符 中文
https://.cpuofbs./rest/postdata?学生姓名=英文名abc&身份证号sfzh=432345678909876543
https://.cpuofbs./rest/postdata?%E5%AD%A6%E7%94%9F%E5%A7%93%E5%90%8D=%E8%8B%B1%E6%96%87%E5%90%8Dabc&%E8%BA%AB%E4%BB%BD%E8%AF%81%E5%8F%B7sfzh=432345678909876543
②、特殊字符,先根据当前页面的编码方式转换,比如,
取其十六进制形式,每两位添加1个%
2.2、ASCII字符编码表
HTML 和 XHTML 用标准的 7 比特 ASCII 代码在网络上传输数据。
2.2.1、“32~126”区段,可显式区段
2.2.2、“0~30及独立的127”区段,设备控制区段
ASCII设备控制代码最初被设计为用来控制诸如打印机和磁带驱动器之类的硬件设备。在HTML文档中这些代码不会起任何作用
3、Base64编码的特殊字符
Base64 encoding character
3.1、base64在http和html中有许多使用场景
1、比如我们在html中表达1个图片文件进行base64编码的src资源,可以
data:image/png;base64,iVBOR0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4f4bLly//BAmVgd1/11/gAAAABJRU5ErkJggg==
1、比如我们在html中表达1个图片文件进行base64编码的src资源,可以
data:image/png;base64,iVBOR0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4f4bLly//BAmVgd1/11/gAAAABJRU5ErkJggg==
2、再比如 对文件进行base64编码,我们上传和下载超大文件,可先对其进行base64二进制编码再压缩后,进行,这样可以极大提升效率并提供了“断点”续传的可能
案例delphi压缩后使用http协议base64上传下载6G超大文件_pulledup的博客-CSDN博客delphi压缩后使用http协议base64上传下载6G超大文件注服务端软件,使用高勇出品GYRestServer系列。欢迎使用,加QQ群咨询174483085一、知识点1、Delphi自带的压缩解压单元system.zlib.pas中核心函数的使用2、服务端http协议ContentType(mime-type)相关列表类型的注册3、Base64编码的规则4、为何要分块断点续传,并使用TFileStream文件流替代内存流TMemoryStream5、Buffe..https://blog.csdn./pulledup/article/details/121455926
3.2、base64字符编码表
base64_百度百科Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。Base64由于以上优点被广泛应用于计算机的各个领域,由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。https://baike.baidu./item/base64/8545775?fr=aladdin
大写A~Z ,小写a~z , 数字0~9, + ,以及1个特殊的“字符A”结尾标识符 ==
6位二进制补齐后的10进制索引 base64 字符 6位二进制补齐后的10进制索引base64字符6位二进制补齐后的10进制索引base64字符6位二进制补齐后的10进制索引base64字符 0 A 16 Q 32 g 48 1 B 17 R 33 h 49 x 2 C 18 S 34 i 50 y 3 D 19 T 35 j 51 z 4 E 20 U 36 k 52 0 5 F 21 V 37 l 53 1 6 G 22 W 38 m 54 2 7 H 23 X 39 n 55 3 8 I 24 Y 40 o 56 4 9 J 25 Z 41 p 57 5 10 K 26 a 42 q 58 6 11 L 27 b 43 r 59 7 12 M 28 c 44 s 60 8 13 N 29 d 45 t 61 9 14 O 30 e 46 u 62 + 15 P 31 f 47 v 63 /代码表示
Shotgun.Js.Base64 = { _table: [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', '', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' ],
3.3、base64字节规则及编码步骤
3.3.1、非base64的字符内存编组方式
通常,计算机的内存中用8位二进制表达1个字符。
比如字符A 0100 0001
01000001
3.3.2、base64的字符内存编组方式
将原本18=8,改编为28=16
比如字符A
00010000 00010000
查找ASCII表10进制结果
16 16
或
00010000 00010000 00000000 00000000
16 16 NUL(null) NUL(null)
然后,比照base64字符编码表
16 16
结果
或
16 16 NUL(null) NUL(null) ---------00000000 00000000刚好比对出2个“A”则用==表示
QQ==
3.3.3、js中base64的编码和解码
// 解决方案 #1 – 在编码之前转义字符串---unescape和escape已弃用 : function utf8_to_b64(str) { return indo.btoa(unescape(encodeURIComponent(str))); }; // function b64_to_utf8(str) { return decodeURIComponent(escape(indo.atob(str))); }; // const bin8 = '01000001', // 00010000 00010000 bin16 = '0001000000010000', // 00010000 00010000 代表QQ bin32 = '00010000000100000000000000000000'; // 00010000 00010000 00000000 00000000 代表QQ== // //00010000 00010000 let encodedData = indo.btoa("A"); // = Base64编码 (缺陷) console.log(encodedData); //: QQ== let decodedData = indo.atob("QQ=="); // = ASCII编码 (缺陷) let decodedData_2 = indo.atob("QQ=="); // = ASCII编码 (缺陷) console.log(decodedData); //: console.log(utf8_to_b64("A")); //: (缺陷) console.log(b64_to_utf8("QQ==")); //: 必须2n幂等 //console.log(2 4);//: 2n幂运算 console.log(b64_to_utf8("QQ")); //: (缺陷) // //解决方案 #2 – 重写atob()和btoa()使用TypedArrays 和 UTF-8 : //注意以下代码对于从 Base64 字符串获取ArrayBuffer也很有用,反之亦然(见下文): // "use strict"; // 字节数组到Base64字符串解码 : function b64ToUint6(nChr) { return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? nChr - 71 : nChr > 47 && nChr < 58 ? nChr + 4 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0; } function base64DecToArr(sBase64, nBlocksSize) { const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, ""); const nInLen = sB64Enc.length; const nOutLen = nBlocksSize ? Math.ceil((nInLen 3 + 1 >> 2) / nBlocksSize) nBlocksSize : nInLen 3 + 1 >> 2; const taBytes = ne Uint8Array(nOutLen); let nMod3; let nMod4; let nUint24 = 0; let nOutIdx = 0; //let nOutId = 0; for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) { nMod4 = nInIdx & 3; nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 6 (3 - nMod4); if (nMod4 === 3 || nInLen - nInIdx === 1) { nMod3 = 0; hile (nMod3 < 3 && nOutIdx < nOutLen) { taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; nMod3++; nOutIdx++; } nUint24 = 0; } } return taBytes; } function uint6ToB64(nUint6) { return nUint6 < 26 ? nUint6 + 65 : nUint6 < 52 ? nUint6 + 71 : nUint6 < 62 ? nUint6 - 4 : nUint6 === 62 ? 43 : nUint6 === 63 ? 47 : 65; } function base64EncArr(aBytes) { let nMod3 = 2; let sB64Enc = ""; const nLen = aBytes.length; let nUint24 = 0; for (let nIdx = 0; nIdx < nLen; nIdx++) { nMod3 = nIdx % 3; if (nIdx > 0 && (nIdx 4 / 3) % 76 === 0) { sB64Enc += "rn"; } nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24); if (nMod3 === 2 || aBytes.length - nIdx === 1) { sB64Enc += String.fromCodePoint(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63)); nUint24 = 0; } } return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? '' : nMod3 === 1 ? '=' : '=='); } function UTF8ArrToStr(aBytes) { let sVie = ""; let nPart; const nLen = aBytes.length; for (let nIdx = 0; nIdx < nLen; nIdx++) { nPart = aBytes[nIdx]; sVie += String.fromCodePoint( nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? (nPart - 252) 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? (nPart - 192 << 6) + aBytes[++nIdx] - 128 : nPart ); } return sVie; } function strToUTF8Arr(sDOMStr) { let aBytes; let nChr; const nStrLen = sDOMStr.length; let nArrLen = 0; for (let nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) { nChr = sDOMStr.codePointAt(nMapIdx); if (nChr > 65536) { nMapIdx++; } nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6; } aBytes = ne Uint8Array(nArrLen); let nIdx = 0; let nChrIdx = 0; hile (nIdx < nArrLen) { nChr = sDOMStr.codePointAt(nChrIdx); if (nChr < 128) { aBytes[nIdx++] = nChr; } else if (nChr < 0x800) { aBytes[nIdx++] = 192 + (nChr >>> 6); aBytes[nIdx++] = 128 + (nChr & 63); } else if (nChr < 0x10000) { aBytes[nIdx++] = 224 + (nChr >>> 12); aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); aBytes[nIdx++] = 128 + (nChr & 63); } else if (nChr < 0x200000) { aBytes[nIdx++] = 240 + (nChr >>> 18); aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); aBytes[nIdx++] = 128 + (nChr & 63); nChrIdx++; } else if (nChr < 0x4000000) { aBytes[nIdx++] = 248 + (nChr >>> 24); aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); aBytes[nIdx++] = 128 + (nChr & 63); nChrIdx++; } else { aBytes[nIdx++] = 252 + (nChr >>> 30); aBytes[nIdx++] = 128 + (nChr >>> 24 & 63); aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); aBytes[nIdx++] = 128 + (nChr & 63); nChrIdx++; } nChrIdx++; } return aBytes; } // 测试 : const sMyInput = "Base 64 u2014 "; const aMyUTF8Input = strToUTF8Arr(sMyInput); const sMyBase64 = base64EncArr(aMyUTF8Input); console.log(sMyBase64); // const aMyUTF8Output = base64DecToArr(sMyBase64); const sMyOutput = UTF8ArrToStr(aMyUTF8Output); console.log(sMyOutput); // const sMyInput_ = "ud869ude95u3400u499bu2a6c7udec7"; const aMyUTF8Input_ = strToUTF8Arr(sMyInput); const sMyBase64_ = base64EncArr(aMyUTF8Input); console.log(sMyBase64_); // 转义符: (€) € € < < &(&) (") 表示为" 将单引号 (') 表示为' //👨👩👧👦为了表达'u1F468u200Du1F469u200Du1F467u200Du1F466'使用16进制或10进制 //㐀䦛𪛇 //𪛇 ; 𣎴 关于UTF-16补充字符与码点 :使用UCS4高低位转换计算后的码点"𣎴"而不是UTF-16的高低位码: // // 将 Base64 字符串解码为 Uint8Array 或 ArrayBuffer : //函数base64DecToArr(sBase64[, nBlockSize])返回一个uint8字节数组。 //如果您的目标是构建16位/32位/64位原始数据的缓冲区,请使用nBlockSize参数(幂等参数) : 这是uint8Array.buffer所包含的字节数 : //uint8Array.buffer.bytesLength属性: //1、ASCII二进制字符(即字符串中的每个字符都被视为二进制数据8位1个字节的字符) //2、或UTF-8编码字符串为1个8位,UTF-16字符串为2个8位,UTF-32字符串为4个8位。 // : 字符编码 : // // "Base 64 u2014 Mozilla Developer Netork" const myArray = base64DecToArr("QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9ZXIgTmV0d29ya=="); // "Base 64 u2014 " // : u2014字节长3 : u占1个字节、全角字符-占2个字节 const myBuffer = base64DecToArr("QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9ZXIgTmV0d29ya==").buffer; console.log(myBuffer.byteLength); //: //当您从服务器检索文档时,服务器通常会随文档发送一些附加信息。这称为 HTTP 标头。这是一个关于文档信息的示例,该信息通过 HTTP 标头与文档一起从服务器传输到客户端时传递
空调维修
- 温岭冰箱全国统一服务热线-全国统一人工【7X2
- 荆州速热热水器维修(荆州热水器维修)
- 昆山热水器故障码5ER-昆山热水器故障码26
- 温岭洗衣机24小时服务电话—(7X24小时)登记报
- 统帅热水器售后维修服务电话—— (7X24小时)登
- 阳江中央空调统一电话热线-阳江空调官方售后电
- 乌鲁木齐阳春燃气灶厂家服务热线
- 珠海许昌集成灶售后服务电话-全国统一人工【
- 乌鲁木齐中央空调维修服务专线-乌鲁木齐中央空
- 新沂热水器故障电话码维修-新沂热水器常见故障
- 诸城壁挂炉24小时服务热线电话
- 靖江空调24小时服务电话-——售后维修中心电话
- 空调室外滴水管维修(空调室外排水管维修)
- 九江壁挂炉400全国服务电话-(7X24小时)登记报修
- 热水器故障码f.22怎么解决-热水器f0故障解决方法
- 营口热水器售后维修服务电话—— 全国统一人工