http到https的过渡

最近https有点火,搜索一下“运商商 流劫持持”,应该能看到好多运营商向网页中强制插入广告的新闻,运营商能这做一是因为流量都要从运营商过路,二是因为http传输的是明文。如果换成https传输数据,数据的安全性可以提高一个档次。

看下文之前请先看《https的使用注意事项》

http到https的切换,道理是很简单的,主要是修改对网址的解析(包括主域名和资源文件的CDN),项目里把“http://”改为“https://”或“//”(自适应协议)。下面是比较详细的改造过程:

1、改配置文件。
配置文件一般存放了项目域名、资源文件域名,所以第一步从这里下手改。
如果开启了https,$_SERVER['HTTPS']非空,一般为on(非https时,在IIS上使用ISAPI方式,该值为off)。
所以,判断是否是https访问的判断条件是 $_SERVER['HTTPS']=='on',我们用 $protocal 表示当前协议,然后把配置里的 http:// 改成 $protocal 。

2、修改项目中的绝对路径。
主要关注几个,jquery路径,二维码路径,微信js地址,轮播图地址,轮播图的点击地址,登录页面的地址。

3、外网资源文件。
如果资源文件很少,可以抓取过来放到自己网站。
如果资源文件很多,可以强制跳转到http页面。(百度图片就是强制跳转到http)

4、统计JS。
百度统计、腾讯统计均支持https,CNZZ现在也支持https(以前的cnzz统计代码不支持https)。
量子统计不支持https。

5、切换到https后可能出现的问题。
a.访问出现502错误;
b.网页打不开,加载时间非常长;
首先看是否是cdn解析问题,如果不能快速解决就切换回http。

总结:
刚始始切换后问题很多,主要特点就是“打不开”、“变慢”。多和运维做些沟通,持续优化https的体验。
https不是绝对安全,如果项目牵扯很多,改造起来难度也很大,量力而行。
记得要保证可以随时切回http。

微信UI开发样式库介绍

整    理:肖雅君

时    间:2016-03-25

说    明:WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页开发量身设计,可以令用户的使用感知更加统一。

一、微信web开发调试工具

1.介绍

2.下载安装

3.界面及功能

二、微信UI开发样式库

1.安装:npm install --save weui

2.元素类型

3.使用方法

3.1 简单的列表

3.2 单/复选列表框

3.3 开关

3.4 表单

3.5 选择框

 

一、微信web开发调试工具

1.介绍

当我们在用浏览器调试基于微信的网页的时候,经常遇到“请在微信打开的情况”,这使得前端在调试页面的时候非常不方便,微信推出了 web 开发者工具。它是一个桌面应用,通过模拟微信客户端的表现,使得开发者可以使用这个工具方便地在 PC 或者 Mac 上进行开发和调试工作。

2.下载安装

下载链接:https://mp.weixin.qq.com/wiki/10/e5f772f4521da17fa0d7304f68b97d7e.html#.E4.B8.8B.E8.BD.BD.E5.9C.B0.E5.9D.80

直接安装即可。

3.界面及功能

运行此开发工具,初始界面:

1

功能:

(1)可以使用自己的微信号来调试微信网页授权页面

(2)可以调试、检验页面的JS-SDK相关功能与权限,模拟部分SDK的输入和输出。

(3)可以使用基于weinre的移动调试功能

(4)可以利用集成的Chrome DevTools协助开发。

使用:

1.输入网址后会弹窗二维码,需手机微信确认后才能使用,如下图

24

3

2.输入网址,能打开页面,但是还是不能调试,需开发者和公众号绑定关系。5为了保证开发者身份信息的安全,对于希望调试的公众号,微信要求开发者微信号与公众号建立绑定关系。具体操作为:公众号登录管理后台,启用开发者中心,在开发者工具——web 开发者工具页面,向开发者微信号发送绑定邀请。

详情见链接:https://mp.weixin.qq.com/wiki/10/e5f772f4521da17fa0d7304f68b97d7e.html

二、微信UI样式库

WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页开发设计,可以使用户的使用感知更加统一。在微信网页开发中使用 WeUI,有如下优势:

同微信客户端一致的视觉效果,令所有微信用户都能更容易地使用你的网站
便捷获取快速使用,降低开发和设计成本
微信设计团队精心打造,清晰明确,简洁大方

1.安装:npm install --save weui

生成文件node_modules:里面包含weui文件夹,weui里有微信样式库使用的demo、样式文件和js文件。

67

 

使用的时候,直接引用weui里的样式文件即可,如下:

<link rel="stylesheet" href="node_modules/weui/dist/style/weui.min.css"/>

法2:无需安装,直接复制weui.css样式到自己的项目文件夹下。

2.元素类型

微信UI封装了几个常用的元素样式,

(1)Button按钮

(2)Cell列表视图

(3)Dialog弹窗

(4)Progess进度条

(5)Toast临时弹窗

(6)Msg page结果页

(7)Article文章段落

(8)Actionsheet可交互的动作集合

(9)Icon图标

3.使用方法

首先要熟悉微信UI类名的命名规律,每个类名上对应了各自的样式,有的父类结合子类代表某个样式。如下,以Cell列表视图作介绍。

一行列表weui_cell分成三个部分组成,类似于将一个表格分成三列,第一列weui_cell_hd、第二列 weui_cell_bd、第三列weui_cell_ft,可以将其理解成head,body,footer。另外,若是要采用自适应布局,需在需自适应的部分加上 class weui_cell_primary,如下图的“新闻”部分。

weui_cell_hd weui_cell_bd weui_cell_ft

3.1 简单的列表

        weui_cells_title:列表标题

         weui_cells:列表集(用来区分不同的列表,里面包含多个weui_cell

         weui_cells_access:跳转入口,结合weui_cell_ft使用(即小箭头,如需要入口箭头,则给weui_cells再添加类名weui_cells_access,并且必须有weui_cell_ft

         weui_cell:一个列表(一个列表里包含weui_cell_hdweui_cell_bdweui_cell_ft

图示:9

代码:列表

3.2 /复选列表框

         单选列表框:weui_cells_radio

         复选列表框:weui_cells_checkbox

          二者都采用隐方式结构(结合显方式)<label></label>[weui_check_label]里嵌套input[weui_check]span[weui_icon_checked]标签,span标签为选中时候的样式标签。

(1)单选

图示:17

代码:单选

(2)复选框

图示:18代码:多选

3.3 开关

         开关:weui_cell_switch

         开关按钮:input[weui_switch]

图示:11

代码:12

3.4 表单

          表单:[weui_cell_form]

         文字:weui_label(姓名)

         输入框:weui_input(请输入姓名号)

         验证码:weui_vcode

         错误报警:weui_cell_warn

         错误报警图标:<i class="weui_icon_warn"></i>

图示:13

代码:14

3.5 选择框

         选择:weui_cell_select

         情况一:箭头在前面weui_select_before结合weui_cell_hd使用

         情况二:箭头在后面weui_select_after结合weui_cell_bd使用

图示:16

代码:15

4.详细介绍

其他元素的使用方法在此不多赘述,微信公众平台开发者文档里结合图片和文字,介绍得非常清楚。

详情见链接:https://mp.weixin.qq.com/wiki/2/ae9782fb42e47ad79eb7b361c2149d16.html#Icon

结合demo:

http://weui.github.io/weui/

列表demo:weui

 

PHP 自动加载总结

自动加载的测试代码

https://github.com/bayuexiong/simple-composer

1. 自动加载

php的加载文件,一般分为三种情况

  1. 直接include/require,不属于自动加载,一般用于PHP5以前的版本。
  2. 使用__autoload(),PHP5.0引入,在PHP5.1.12之后不再推荐使用。
  3. 使用spl_auoload_register(),现在使用比较多,于PHP5.1.12之后加入,提供了一种更加灵活的方式加载文件。

具体实例

第一种没什么说的。主要还是看第二种和第三种。

假设在一个项目里面有两个文件

Demo.php

class Demo
{
# coding
}

index.php

function __autoload($class_name)
{
$file = dirname(__FILE__) . '/' . $class_name;
if (file_exist($file)) {

include($file);

}

}

$obj = new Demo();

Demo.phpindex.php只要在一个同级目录内,php变会很智能的加载Demo.php,不需要显示的操作。

但是这里还是存在弊端的,比如一个项目中只能有一个__autoload(),这也意味着自动加载的价值变得很低,于是PHP便在PHP5.1.12版本之后添加了spl_autoload_register(),它接受一个回调函数,使得自动加载更加的灵活。

修改index.php

function my_autoload($class_name)

{

$file = dirname(__FILE__) . '/' . $class_name;

if (file_exist($file)) {

include($file);

}

}

spl_autoload_register('my_autoload');

$obj = new Demo();

之前的Demo.php不做修改,将index.php如此修改,便可以同样的功能。

关于spl_autoload_register()更多的内容可以查看官方文档。

http://php.net/manual/zh/function.spl-autoload-register.php

 TIPS
注意类名和文件名必须保持一致!!!

2. Composer

在5.3之后,Composer大行其道,号称PHP未来的希望。。。

使用Composer自动加载时只要引入一个自动加载文件就可以了。

include_once('vendor/autoload.php');

那么Composer的自动加载时怎么实现的呢,其实也是依靠spl_autoload_register()

首先Composer存储三对数组

class=>dir
namespace=>array(dir, dir, dir)
PSR4=>array(dir, dir1, dir2...)

然后在autoload.php, 存在一个loader,可以触发spl_autoload_register,
一旦触发,Composer会对触发的类型进行分析,选择合适的数组,将真实的地址提取出来,然后include,原理还是很简单,推荐大家自行查看一下Composer的自动加载的代码。

关于composer的一个Tips

在上线代码时可以使用composer dump-autoload -o 转换PSR-0/4 autoloadingclassmap 获得更快的载入速度。这特别适用于生产环境,但可能需要一些时间来运行,因此它目前不是默认设置。至于为什么,看完源代码就清晰了。

3. 简单实现一个Composer自动加载

简单实现ClassMap的自动加载功能

https://github.com/bayuexiong/simple-composer/tree/master/vendor

使用代码和Composer一样。

include 'vendor/autoload.php';

$obj = new Demo('gg');

$obj->sayName();

$obj2 = new Other('aa');

$obj2->sayName();

4. 如何选择自动加载机制

  1. 在程序一开始运行的时候,使用数组,将项目内所有的文件记录下来,实现自动加载(如果使用cache,应该还hold的住),symfony使用这种形式,代码如下。
    https://github.com/symfony/class-loader/blob/master/ClassMapGenerator.php
  2. class名和路径对应,便于查找,但是这样缺乏灵活性,框架的侵入性太强了,代码很受框架的限制,像ThinkPHP,CI就是使用这种形式。
  3. 组合使用,像Laravel就是使用PSR4和symfony的classLoader。

5. CI框架的自动加载

现在公司使用CI框架的情况比较多,所以对CI框架的自动加载做一些详细的介绍。

对于一个普通的CI加载类的方式:

 $this->load->library('myclass');

CI框架的内部是如何运行的呢?首先上个流程图

QQ截图20160314174227

具体的实现可以查看源代码,都在system/core/Loader.php文件下面。

其实CI框架的自动加载并没有借助spl系列的函数,而是直接查找文件的方式来自动加载,这可能与CI框架诞生的年岁有关,在那个时期不失为一种优秀的自动加载方法。

但是现在来说,算不上优秀,其对命名的规范太过苛刻了,效率也谈不上高效,当然CI框架的整体速度还是很快的,毕竟像symfony之流的框架为了实现完全解耦,付出了很多性能上的代价。

Tips

对于一个普通的加载类
$this->load->library($library, $param, $object_name);
1. $library 可以是一个数组key代表需要加载的类,value则是obejct_name。
2. $param 需要一个数组,作于传入构造器中的值
3. $object_name$this->load->model(calss, object_name)中第二个参数一样,加载完之后可以$this->object_name->sayHello()

具体的可以结合CI的文档再加上阅读CI的源代码,的确CI的文档相比其他的框架比较全面,但是一些技巧也没有详尽的介绍。

6. 小结

使用Composer吧!使用RSP4命名空间规范吧!这样各个组件与组件之间,自己的代码和别人的代码都可以无痛的结合,不需要花费额外的精力去处理文件加载的问题。

7. 补充

  1. 命名空间,命名空间提供了一种灵活的效率更高的辅助自动加载的方法。
  2. PSR4 规范命名空间的定义,是最近比较流行的命名空间规范。

材料参考:

  1. https://github.com/qinjx/adv_php_book/blob/master/class_autoload.md
  2. spl_autoload_register
  3. __atuoload

UEditor 独立图片上传功能

一、下载使用ueditor

1、从官网上下载UEditor富文本编辑器

2、学会部署使用ueditor。

二、实现方法

1、在html中放置UEditor编辑器,为了不使独立上传图片功能影响到正常的编辑器,这里要多设置一个UEditor编辑器并且需要隐藏。如下代码,myEditor是正常使用的编辑器,upload_ue为隐藏的编辑器。

<script id="myEditor" type="text/plain"></script>
<script id="upload_ue" type="text/plain" style="display:none"></script>

2、实例化编辑器,并侦听图片上传,实现图片预览

<script type="text/javascript">
    var _editor;
    $(function() {
        //实例化一个编辑器,防止在上面的editor编辑器中显示上传的图片或者文件
        _editor = UE.getEditor('upload_ue');
        _editor.ready(function () {
            //侦听图片上传
            _editor.addListener('beforeInsertImage', function (t, arg) {
                //单图预览
                $("#pic_lsit").attr("src", arg[0].src); 
                //多图预览
                for (var i = 0; i < arg.length; i++) {
                    $("#pic_list").append('<div id="photos'+i+'" style="float:left;"><input type="hidden" name="photos[]" value="'+arg[i].src+'" /><img src="'+arg[i].src+'" width="150" height="150" /><a onclick="removePhoto('+i+')">删除</a></div>');
                }
            });
        });
    });
</script>

ps:实例化编辑器之后,一定要确保编辑器上传图片功能能够实现。

3、添加一个按钮,并绑定onclick事件,用于触发编辑器中的上传图片功能。

<button onclick="upImage()">上传图片</button>
<script>
function upImage() {
    var myImage = _editor.getDialog("insertimage");
    myImage.open();
}
</script>

三、参数配置

1、在/ueditor/php/config.json中修改相关配置

/* 上传图片配置项 */
"imageActionName": "uploadimage", /* 执行上传图片的action名称 */
"imageFieldName": "upfile", /* 提交的图片表单名称 */
"imageMaxSize": 2048000, /* 上传大小限制,单位B */
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
"imageCompressEnable": true, /* 是否压缩图片,默认是true */
"imageCompressBorder": 1600, /* 图片压缩最长边限制 */
"imageInsertAlign": "none", /* 插入的图片浮动方式 */
"imageUrlPrefix": "", /* 图片访问路径前缀 */
"imagePathFormat": "/test2/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */

下载测试代码ueditor 独立图片上传

专题模块化改版

整    理:肖雅君

时    间:2016-03-04

说    明:专题模块化:手机端仍需前端切,PC端改用统一的模板,只需将切好的WAP端代码复制到模板里,再将css样式中的尺寸大小变成WAP端的2倍即可。(钱昱成正做成后台,后续会更新此文档。)

一、新专题步骤

1.<!doctype html>前

2.<head></head>

3.<body></body>

二、新老专题比较

1、顶部php

2、头部

3、头部以及右侧分享部分

4、右侧栏部分

5、评论模块不变

6、公共底部

 

一、新专题步骤

  1. <!doctype html>

<?php

include_once('../include/global.php');

$special_id = 10379;

$share_title = '产后抑郁,产后抑郁症,产后抑郁如何治疗.。。。 ';//分享的标题[修改]

$share_content = '新生命的降生.。。。';//分享内容[修改]

$share_pic = 'http://www.ci123.com/special/survey-yiyu/styles/images/share_pic.jpg';//分享的图片[修改]

include_once('../global/new_special/info.php');

if(isMobile()){

header("Location:http://m.ci123.com/special/survey-yiyu");//手机端专题链接[修改]

die();

}

?>

<!doctype html>

<html>

</html>

2.<head></head>

<head>

<meta charset="utf-8">

<title>惊!九成产妇有产后抑郁倾向?!</title>//专题标题[修改]

<meta name="renderer" content="webkit">

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

<?php include_once('../global/new_special/share.php');?>

<link rel="stylesheet" href="styles/style_sub.css">//主要内容的样式[修改]

</head>

3.<body></body>

<body>

<?php include_once("../global/header.php");?><!--育网公共头部php-->

<div class="wrapper-special">

<div class="special-content">

<!--专题头部-->

<div class="part-content part-header">

<?php include_once('../global/new_special/part1.php');?><!--专题头部php-->

</div>

<!--专题头部-END-->

<!--右侧栏-->

<div class="part-content">

<?php include_once('../global/new_special/part2.php');?><!--右侧栏[“往期回顾+更多推荐”]php-->

</div>

<!--右侧栏-END-->

<!--左侧主体内容 -->

<div class="part-main">

<!-- 此处放主体内容 \ 此处放主体内容 \ 此处放主体内容-->

<!--左侧主体内容-END-->

</div>

</div>

</div><!—整体页面-->

<!--底部版权-->

<?php include_once('../global/new_special/footer.php');?>

<!--底部版权end-->

<div style="display:none;"><script src="http://s11.cnzz.com/stat.php?id=1257703690&web_id=1257703690" language="javascript"></script></div>//统计代码[修改]

</body>

 

二、新老专题比较

1、顶部php

原版:1-2

新版:1-3

改变内容:

(1)替换掉原来的帖子id(现在从库里取,需从后边编辑帖子那边添加)

(2)分享文案只需在开头添加

(3)需引入include_once('../global/new_special/info.php');(必须在$special_id后面引入)

2、头部

原版:1-2

新版:1-4

3、头部以及右侧分享部分

3

代码:<?php include_once('../global/new_special/part1.php');?>

4、右侧栏部分

4

代码:<?php include_once('../global/new_special/part2.php');?>

5、评论模块不变

5

引入此段代码:<?php include_once('../global/reply.php');?>

6、公共底部

6

代码:<?php include_once('../global/new_special/footer.php');?>

 

【前端技术文档】http相关知识

整    理:曹燕

时    间:2016-03-04

说    明:http的定义、请求响应模型、TCP三次握手、使用wireshark工具抓包

1.定义

http: hypertext transfer protocol(超文本传输协议),是用于从WWW服务器传输超文本到本地浏览器的传送协议。http是互联网上应用最为广泛的网络协议。所有的WWW文件都必须遵守这个标准。它由请求和响应构成,是一个标准的客户端服务器模型。

2.http请求响应模型

http协议永远是客户端发起请求,服务器端回送响应。

http协议是一个无状态的协议,同一个客户端的这次请求和上次请求没有对应关系。图片1

①http客户端发起请求,创建端口;

②http服务器在端口监听客户端的请求;

③http服务器向客户端返回状态和内容。

 

3.访问某个网址的整个流程

(1)建立连接

①chrome搜索自身的DNS缓存(如有没有baidu.com及ip地址,一般缓存1分钟,如果有缓存看是否过期)【方法:chrome://net-internals/#dns】;

②当浏览器没有找到缓存或缓存已经过期,则搜索操作系统自身的DNS缓存;

③如果没找到,则读取本地的host文件;

④如果host文件中没有,则浏览器发起一个DNS的系统调用;

⑤宽带运营商服务器查看自身缓存;

⑥运营商服务器发起一个迭代的DNS解析请求;

⑦运营商服务器把结果返回操作系统内核并缓存起来;

⑧操作系统内核把结果返回给浏览器;

⑨最终浏览器拿到了www.baidu.com的ip地址

⑩浏览器获得对应的ip地址之后,发起三次握手。(详见下文)

(2)浏览器发送请求

TCP/IP连接建立起来之后,浏览器就可以向服务器发送请求了。例如用http中的get方法请求一个根域里的一个域名,采用了http1.0的某个协议;【应用于资源的方法、资源的标识符和协议的版本号】

(3)服务器返回响应

服务器接受这个请求,根据路径参数,经过后端的一些处理,把处理之后的结果数据返回给浏览器(例如百度的html页面)【信息的协议版本号、状态码,MIME信息包括服务器信息、实体信息和可能的内容】

(4)浏览器渲染

浏览器拿到了百度的完整html页面代码,在解析和渲染这个页面的时候,里面的css/js/静态图片等静态资源,同样是一个个http请求,需经过前面的7步。

浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现给用户,然后与服务器断开连接。

 

3.TCP连接中的三次握手

3.1概念

确认比特ACK——只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效;

同步比特SYN——同步比特SYN置为1,就表示这是一个连接请求或连接接受报文;

3.2三次握手

①浏览器:客户端发送syn包到服务器,并进入SYN_SENT状态,等待服务器确认【你能听到我说话吗,我们聊聊?】

②服务器:服务器收到syn包,必须确认客户的SYN,同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态【我能听到你说话,我们可以聊聊】

③浏览器:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手【好的,那我们开始聊吧】

3.3利用工具Wireshark抓http、tcp包结果:图片2

4.http请求头

  • Accept:浏览器可接受的MIME类型;
  • Accept-Charset:浏览器可接受的字符集;
  • Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip;
  • Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到;
  • Authorization:授权信息;
  • Connection:表示是否需要持久连接。如果这里的值为“Keep-Alive”,或者请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间;
  • Content-Length:表示请求消息正文的长度;
  • Cookie:这是最重要的请求头信息之一;
  • Host:初始URL中的主机和端口;
  • If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答;
  • Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝;
  • Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面;
  • User-Agent:浏览器类型。

5.http响应头

  • Allow:服务器支持哪些请求方法(如GET、POST等);
  • Content-Encoding:文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型;
  • Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据;
  • Content-Type: 表示后面的文档属于什么MIME类型,如text/plain,text/html;
  • Date:当前的GMT时间;
  • Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它;
  • Last-Modified:文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态;
  • Location:表示客户应当到哪里去提取文档;
  • Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计。

 

相关文档:http 1.1 和 http1.0 主要区别

定义SASS函数,方便WAP\PC端的样式数值快速切换

编    写:晋哲

时    间:2016-03-04

说    明:因移动端页面样式都是原尺寸的二分之一,PC专题页固定模板直接引用移动端页面的样式还需要返工去将所有的数值型属性值改回来,为方便两端之间的样式切换,提高效率,建议此类专题使用SASS去写样式,并使用下面定义的函数。

//定义函数
@function math($num) {
    @return $num / 2;
}

//SASS中使用函数,如以下常用的一些数值型属性
.icon {
    top: math(40%);
    margin: math(20px);
    width: math(100px);
    height: math(40px);
    font-size: math(30px);
    background-position: math(-10px) math(-20px);
    background-size: math(240px);
}

//生成的移动端CSS代码
.icon {
    top: 20%;
    margin: 10px;
    width: 50px;
    height: 20px;
    font-size: 15px;
    background-position: -5px -10px;
    background-size: 120px;
}

当需要生成PC端样式时,只需修改函数内的被除数即可。

支付宝升级补充文档

前言

所有以下的demo均是基于支付宝php utf-8编码的demo,其他情况请自行核对。

知识补充\变化

  • 一个商户最核心的配置为:
    1. 商户支付宝账号id(以2088开头的纯16位数字)
    2. [公共基本配置]选用的编码格式(utf-8、gbk)
    3. [公共基本配置]跟支付宝通信用的证书(cacert.pem)
  • 其他配置:
    1. 安全校验码(当sign_type=md5时使用)
    2. 商户私钥rsa_private_key.pem、支付宝公钥rsa_public_key.pem(当sign_type=rsa时使用)
  • 新的请求接口为https://mapi.alipay.com/gateway.do?,而且代码里面不需要预先提交获取token
  • 支付宝订单在3个月以后会关闭(3个月之内都可以发起退款),在关闭之后会主动推送一次。(这里不需要做任何的订单状态更新的处理)
  • 支付成功同步的Post请求报文中的NotifyId会在10分钟以后过期。而这个NotifyId会关系到验签中的获取支付宝系统结果的返回是否为true(所以同步的报文以后再来做验签其实没有意义)

小结

接入方

  1. 给到商户的核心配置(商户支付宝账号id)
  2. 根据加密方式提供不同的“验签凭证”
  3. 注意是否签约自己需要的接口产品(不然请求会302跳转到错误码ILLEGAL_EXTERFACE)

资料引用

关于定位的一些参考

整  理:朱 兵
时  间:2016-02-05
说  明: 定位的相关知识

摘要:关于定位,分为GPS定位和网络定位2种。GPS定位,精度较高,可达到10米,但室内不可用,且超级费电。网络定位,分为wifi定位和基站定位,都是通过获取wifi或者基站信息,然后查询对应的wifi或者基站位置数据库,得到的定位地点。定位数据库可以不断完善不断补充,所以,越定位越准确。

一、常见的定位:

GPS全球定位。

常见的GPS定位的原理可以简单这样理解:由24颗工作卫星组成,使得在全球任何地方、任何时间都可观测到4颗以上的卫星, 测量出已知位置的卫星到用户接收机之间的距离,然后综合多颗卫星的数据就可知道接收机的具体位置。

在露天环境下效果较好,获取位置信息非常精确。适合移动设备。 

缺点:在地铁等位置效果较差

IP地址定位。

适用于接入互联网的设备,通过浏览器是将位置信息发送给 ISP 服务商来解析,其IP 地址与服务商所在位置有关,可能与用户所在位置不同,所以这种方式的解析容易出现偏差。 

另外,由于国内大部分的省都是以省级为单位划分基站对外访问 IP ,也就是说,同样一个出口 IP,后面的对应用户
可能是跨多个城市的。也有一部分省是按照市一级为单位划分的,但是位置偏远。
备注:IP定位很方便,但是数据不准,需要及时更新,有很多商业化的服务。

WiFi定位。

设备只要侦听一下附近都有哪些热点,检测一下每个热点的信号强弱,然后把这些信息发送给网络上的服务端。服务器根据这些信息,查询每个热点在数据库里记录的坐标,然后进行运算,就能知道客户端的具体位置了。一次成功的定位需要两个先决条件:客户端能上网 ,侦听到的热点的坐标在数据库里有。

优点:这种方式与GPS效果同样精确,适用于室内环境的移动设备。

缺点:

  • 你的这个wifi信号,如果在数据库中没有被记录在案,那就没法定位了。比如,如果你买了个新的无线路由器,靠它肯定是没法帮助你的移动设备定位的。
  • 数据更新有延迟,WIFI覆盖并不大,局限
    原理说明:当你的移动设备需要使用wifi定位的时候,它会搜索周围的wifi信号,同时在数据库中搜索,得到地理位置的数据,加上定位提供商收集的海量数据,能够构建出信号的“指纹”,比基站定位更精准。

④基站定位

我们把手机基站的覆盖范围想像成一个个以基站为圆心的圆,需要定位时,手机就向周边多座基站发送测量信号,并计算这些测量信号到达基站所需要的时间,推算出手机距离基站的直线距离,再经过数学运算,手机位置坐标就可由3个基站圆的交点来确定。

优点:LBS定位的优势是方便、成本低,因为它是通过手机进行定位的。理论上说,只要计算三个基站的信号差异,就可以判断出手机所在的位置,而且用户所持终端只需一部手机即可。因此,只要用户手机有信号,就可以随时进行位置定位,而不受天气、高楼、位置等影响。

缺点:定位精度随所处位置基站数不同会有变化。

百度地图等在web开发时并不提供相关api

二、测试结果:

初步得到的结果:GPS>WiFi/基站>IP

1、GPS和WIFI相对测试的结果较好。
2、局限性:WIFI效果较好,但是局限性很大。基站定位在web开发时比较麻烦
3、目前比较好的方式,就是读取GPS的相关信息(比如经纬度等等),再做进一步操作。
4、在精准度要求比较高的情况下,并不推荐使用ip定位。ip定位好处是:并不需要用户授权,方便。

三、业务说明:

以百度地图为例

1、APP开发的话
百度定位sdk,综合了wifi定位、基站定位

2、web开发的话

浏览器定位

浏览器定位插件,封装了标准HTML5定位,并且包含纠偏模块。

html5定位:拿到的是GPS的数据,定位准确

备注:获取经纬度数据,想获得地址,需要纠偏,再使用接口获得。

鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的。

Internet Explorer 9、Firefox、Chrome、Safari 以及 Opera 支持地理定位。

注释:对于拥有 GPS 的设备,比如 iPhone,地理定位更加精确。

更多可参考geekman的文章:http://blog.geekman.vip/archives/446

另外,浏览器定位插件也是混合定位,获取了wifi、基站信息用以定位,对于拥有 GPS 的设备,比如 iPhone,由于获得GPS信息,使得地理定位更加精确。

★浏览器定位,最好使用在手机浏览器上,会更加准确,也更加符合使用场景。PC浏览器上,建议使用IP定位。

通过网络获取IP信息,然后查询IP数据库,获取相应的地址信息。

IP数据库也是可以完善补充,越来越丰富的,所以也是越使用越准确的。

但如果IP有跳转,有篡改等,那么IP定位就会不准确了。

demo:http://developer.baidu.com/map/jsdemo.htm#i8_2

③web接口
嫌开发不方便,可以直接调用web接口,体验更快,缺点是次数限制。
育儿网对一些接口进行了封装(100w次)
根据ip获取地理位置
根据经纬度获取地理位置(百度接口)

具体api地址在:http://api.xinfotek.com/apidoc/doc/

关于JSAPI/webAPI的小小说明

1、js是浏览器端,而web是服务端。

2、在使用上Web更简单,若只想使用服务,直接通过调用接口获取结果的话,并且需求量并不大的 时候,建议使用web。(百度js调用次数不限)

3、想展示地图,或者超过接口限制,比较复杂的web开发,想要的功能并没有提供相应的接口,会需要用到js。

Tip:使用之前需要申请秘钥.

秘钥分为浏览器端,服务端,

为了安全性可设置白名单:
浏览器端是设置域名:如*.ci123.com,只能在该域名下访问

服务端是设置ip白名单,不限制的话 0.0.0.0/0
3、在微信中使用

引用微信js即可使用

给的接口只有两类,一类是用内置浏览器(使用并不多),一类是得到想要的配置

示例一:使用微信内置地图查看位置接口
wx.openLocation({
latitude: 0, // 纬度,浮点数,范围为90 ~ -90
longitude: 0, // 经度,浮点数,范围为180 ~ -180。
name: '', // 位置名
address: '', // 地址详情说明
scale: 1, // 地图缩放级别,整形值,范围从1~28。默认为最大
infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转

});
示例二:获取地理位置接口
wx.getLocation({
    type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
    success: function (res) {
        var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
        var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
        var speed = res.speed; // 速度,以米/每秒计
        var accuracy = res.accuracy; // 位置精度
    }
});
 
四、其他说明
①特殊说明:
1、通过百度jsapi测试结果看,通过ip定位城市效果也会存在比较大的误差,更别提精确定位。
但是只要数据库足够丰富,定位结果会准确的多,但是成本会特别高。
2、对于GPS坐标转换成使用百度api需要转换百度坐标(纠偏)
②自己写的参考demo
1、js版(利用html5定位,再调用百度api,调用次数不限)
好处:去除了地图展示等一些功能,直接显示位置。
演示效果
QQ图片20160205154740
2、web请求,这个比较简单,直接根据经纬度调用接口。
好处:少一次调用
③参考资料/网站:
3、百度开发平台:http://lbsyun.baidu.com/

 

 

【前端技术文档】gulp spriter 插件使用

整    理:肖雅君

时    间:2016-02-05

说    明:gulp-css-spriter 将css代码中的切片图片合并成雪碧图

一、下载安装gulp

1.1 下载安装node.js

1.2 命令行测试是否安装成功

1.3 定位到项目

1.4 安装gulp

二、开始使用gulp

2.1 新建gulpfile.js文件

三、gulp-css-spriter

3.1 gulp-css-spriter使用步骤

3.2  使用技巧

一、下载安装gulp

1.1 下载安装node.js

下载链接:https://nodejs.org/en/   下载后直接安装即可。

1.2 命令行测试是否安装成功

Cmd

输入命令:Node –v  看是否返回node版本号,若是返回则安装成功。

输入命令:npm –v  同上是否返回npm的版本号

如下图:则是安装成功。

1

Ps: NPM是基于命令行的node包管理工具,它可以将node的程序模块安装到项目中,在它的官网https://npmjs.org/ 中可以查看和搜索所有可用的程序模块。

1.3 定位到项目

直接输入d:  按回车键,进入d盘,再进入到安装文件夹,如下图:

2

1.4 安装gulp

遇到的问题:

参考资料中有sudo npm install –g glup安装命令,但是是出错的。

3

Sudo是以管理员身份执行命令,是切换到最高用户权限,su是切换用户,这是linux里才有的,windows是没有的。

将sudo去掉,用npm install -g gulp安装也是不行的。

4

使用npm install --global gulp是可以安装的,但是有一个warn警告。

5

查看版本号也是能查看到的:

6

二、开始使用gulp

2.1 新建gulpfile.js文件

建立gulpfile.js文件,作为它的主文件,放入到自己的项目目录中。

然后在gulpfile.js中定义自己的任务。

 

三、gulp-css-spriter

功能:将css代码中的切片图片合并成雪碧图

3.1 gulp-css-spriter使用步骤

(1)安装gulp-css-spriter

输入命令npm install gulp-css-spriter

7

安装成功后自己建的文件里会产生node_modules文件夹,里面会有一个刚安装的gulp-css-spriter文件夹。

89

(2)配置gulpfile.js文件

var gulp = require('gulp'),

spriter = require('gulp-css-spriter');

 

gulp.task('css', function(){

var timestamp = +new Date();

//需要自动合并雪碧图的样式文件

return gulp.src('styles/style.css')//雪碧图的原路径文件

.pipe(spriter({

// 生成的spriter的位置

'spriteSheet': 'combine/images/sprite'+timestamp+'.png',

// 生成样式文件图片引用地址的路径

// 如下将生产:background:url(images/sprite20160205.png)

'pathToSpriteSheetFromCSS': 'images/sprite'+timestamp+'.png'

}))

//产出路径

.pipe(gulp.dest('combine'));

});    //产出路径

2

(3)执行编译输入命令:gulp css

55

(4)编译前后文件目录截图对比

a.编译之前:

合并前文件目录:

11

合并前style.css样式:

22

合并前图片文件夹:

44

b.编译之后:

合并后文件目录:

66

combine文件夹里的文件:

77

combine里的style.css:

88

combine里的图片文件夹:

99

(5)可能出现的问题:

在编辑后可能会出现如下问题:

11

Cannot find module ‘gulp-minify-css’;

需要再次安装gulp-minify-css。执行命令:npm install gulp-minify-css

12

安装完毕后再次编译:(点击可查看动图编译过程)

15

 3.2  使用技巧

gulp-css-spriter默认会对样式文件里,所有的background/background-image的图片合并,但实际项目中,我们不是所有的图片都需要合并。

background-image: url(../images/data3.png?__spriter);//有?__spriter后缀的合并

background-image: url(../images/part-bg.png); //不合并

修改下面文件可以按需合并:

node_modules\gulp-css-spriter\lib\map-over-styles-and-transform-background-image-declarations.js

13

48行开始的if-else if代码块中,替换为下面代码

位置:

14

// background-image always has a url 且判断url是否有?__spriter后缀

if(transformedDeclaration.property === 'background-image' && /\?__spriter/i.test(transformedDeclaration.value)) {
transformedDeclaration.value = transformedDeclaration.value.replace('?__spriter','');
return cb(transformedDeclaration, declarationIndex, declarations);}
// Background is a shorthand property so make sure `url()` is in there 且判断url是否有?__spriter后缀
else if(transformedDeclaration.property === 'background' && /\?__spriter/i.test(transformedDeclaration.value)) {
transformedDeclaration.value = transformedDeclaration.value.replace('?__spriter','');
var hasImageValue = spriterUtil.backgroundURLRegex.test(transformedDeclaration.value);
if(hasImageValue) {
return cb(transformedDeclaration, declarationIndex, declarations);}
}

 

再次执行即可。

 

参考链接:

https://github.com/laoshu133/gulp-css-spritesmith

https://github.com/aslansky/css-sprite