微信公众平台,开放平台等相关基础知识

开放平台
释意:开放互联
平台提供:创建移动应用、创建网站应用、绑定公众帐号、创建公众号第三方平台
核心作用:提供UnionID,可以作为一个userCenter来管理所有渠道汇集过来的微信用户,识别用户唯一性。

一、简要描述和已开放功能
1、移动应用
接入微信开放平台,让你的移动应用支持微信分享、微信收藏和微信支付。
1.1、微信登录
1.2、微信分享与收藏
1.3、微信支付
1.4、微信智能接口(图像识别,语音设别,语音合成,语义理解)
2、网站应用
接入微信开放平台,让你的网站支持使用微信帐号来登录
2.1、微信扫码登录
2.2、微信智能接口(语义理解)
3、绑定公众帐号
接入微信开放平台公众帐号开发,为亿万微信用户提供轻便的服务。
(另翻一篇详说)
4、公众号第三方平台
成为公众号第三方平台,为广大公众号提供运营服务和行业解决方案
(暂无研究)

二、网站应用实践的相关记录
1、创建过程

1.1.1、填写基本信息
附件:微信开放平台网站信息登记表
1.1.2、填写网站信息,即授权回调域
只需要填写域名即可。
1.1.3、提交审核
1.2、据了解,之前起名,不受限制,现在对名字要求严格,尽量保持唯一性。所以对于已经出现过的名字,要求提供证明材料,证明对此名字有绝对的使用权。也许不久的将来,微信也会出一个商标名注册类似的东西吧。。。
1.3、审核提示是7个工作日,实际非常快,两三个小时可能就通过了审核。

2、程序实践
2.1、请求code
2.1.1、跳转方式获取code

2.1.2、jssdk方式获取code





测试网站应用,jssdk方式的登录




2.2、通过code获取access_token
<?php
$appid = 'wx597628e7e8fdbd47'; // 公众平台下,网站应用, 孕期提醒
$appsecret = 'fc02648b9f7698733b0bb45dbe1fcb88';
$state = $_GET['state'];

if ($state != $session_state) {
// die("授权终止");
}
$code = $_GET['code'];

$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code";
$r = curlRequest($url);
var_dump($r);

3、各类功能接口汇总
3.1、请求code
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
3.2、通过code获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
3.3、刷新access_token有效期
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
3.4、检验授权凭证(access_token)是否有效
https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
3.5、获取用户个人信息(UnionID机制)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

公众平台
释意:微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开发接口则是提供服务的基础,开发者在公众平台网站中创建公众号、获取接口权限后,可以通过阅读本接口文档来帮助开发。
平台提供:订阅号,服务号,企业号,小程序
核心说明:微信公众平台开发是指为微信公众号进行业务开发;不要跟开放平台弄混淆。
其他说明,详见官方文档。https://mp.weixin.qq.com/wiki

一、简要描述和已开放、可申请功能 https://mp.weixin.qq.com/wiki
1、权限(开始前必读——公众号接口权限说明)
2、接口测试号申请:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
3、接口在线调试:http://mp.weixin.qq.com/debug/
4、其他先看看官方文档吧。。。。。

二、微信内网页授权登录以及指定内容分享
1、授权登录
https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.46117882231840723#1
2、指定分享内容
https://mp.weixin.qq.com/wiki?action=doc&id=mp1421141115&t=0.9996787578927169#fxjk
关于指定分享内容,之前尝试过,在非绑定域名下调起绑定域名下的资源,指定分享内容,结果是失败了。(有接触过,深究过的,一起探讨下,有没有其他可以绕过去的办法)

之前在专题那边封装的一个微信分享

数据加密技术

目录:
数据加密技术有哪些分类
每个分类的实现方式和常见算法
正文:
一、数据加密技术有哪些分类
对称加密算法
非对称加密算法
单向加密(散列算法)
散列算法不是加密算法, 因为如果目的是加密,必须满足的一个条件是加密过后可以解密。但是散列算法是无法从结果还原出原始数据的。
二、每个分类的实现方式和常见算法
对称加密算法
1、定义:
对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在大部分对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
在PHP中也有封装好的对称加密函数:Urlencode/Urldecode base64_encode()/base64_decode()
严格的来说,这两个函数其实不算是加密,更像是一种格式的序列化。
2、常见的加密算法:
DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;据说是要取代DES

3、DES算法:
对称加密算法中最经典的算法莫过于DES加密算法。DES加密采用的是分组加密的方法,使用56位密钥加密64位明文,最后产生64位密文。DES算法的基本流程如下图所示。

现在对图的整个流程做简要的分析。DES对64位的明文分组M进行操作,M经过一个初始置换IP置换成m0,将m0明文分成左半部分和右半部分m0=(L0,R0),各32位长。然后进行16轮完全相同的运算,这些运算称为函数f,在运算过程中,数据与密匙结合。经过16轮运算之后,可以看到第16轮运算,将右侧第15轮运算的结果(R15)作为左侧运算的最终结果(L16),而右侧最后的结果(R16)为左侧第15轮运算结果(L15)和函数f运算结果的异或运算所得。此后,再将左、右部分合在一起经过一个逆置换,输出密文。
实际加密过程要分成两个同时进行的过程,即加密过程和密钥生成过程,如下图所示。

如上图所示,在16轮循环的每一轮中,密匙位移位,然后再从密匙的64位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的32位数据,在将其置换一次。这四步运算构成了图1中的函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。该操作重复16次。
DES算法的解密过程和加密过程几乎完全相同,只是使用密钥的顺序相反。

4、优缺点
优点:算法公开、加密解密的速度比较快,适合数据比较长时的使用。
缺点:
1、加密方和解密方使用同一个密钥,安全性得不到保障。
2、密钥传输的过程不安全,且容易被破解,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。

非对称加密算法
1、定义:
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
2、常见的加密算法:
RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;
DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

3、http://www.cnblogs.com/zfxJava/p/5295957.html理解公钥和私钥(划重点)

4、优缺点
优点:对称加密算法不能实现签名,因此签名只能非对称算法。比对称加密算法更加安全。
缺点:
1、由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。
2、公钥传输的过程不安全,易被窃取和替换,由此产生了数字证书。

单向加密(散列算法)
1、定义:
属于摘要算法(哈希/散列算法),不是一种加密算法,作用是把任意长的输入字符串变化成固定长的输出串的一种函数。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。
2、常见的散列算法:
1、MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。
2、SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值;

3、MD5加密注意点:

md5()为单向加密,没有逆向解密算法,但是还是可以对一些常见的字符串通过收集,枚举,碰撞等方法破解;所以为了让其破解起来更麻烦一些,所以我们一般加一点盐值(salt)并双重MD5;
例: md5(md5($password).'ylcf')
ylcf就是盐值。
4、特点
雪崩效应、定长输出和不可逆。

vueJs父子组件通信以及vue-resource的使用

整   理:晋 哲

时   间:2017-01-03

说   明:实例展示vueJs如何调取数据

一、父子组件基本代码块

/* 父组件 */
<div id="product_list">
    <nav-item></nav-item>
</div>

/* 子组件模块 */
<template id="nav-model">
    ……
</template>

/* 子组件对象 */
Vue.component('nav-item', {
    template: '#nav-model',
    ……
});

/* 主体构造器 */
var ins = new Vue({
    el: '#product_list',
    data: [
        ……
    ],
});

二、父子组件自定义事件,用于在组件树中通信
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件;
使用 $dispatch() 派发事件,事件沿着父链冒泡;
使用 $broadcast() 广播事件,事件向下传导给所有的后代。

三、常用父子组件通信方式
1、父组件向子组件传递数据
使用 Props 传递数据

2、子组件向父组件传递数据
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件。

四、vue-resource的使用(在一个Vue实例内使用$http)
1、GET请求
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);

2、POST请求
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

参考网址:
http://vuejs.org.cn/guide/components.html#使用-v-on-绑定自定义事件
http://www.doc00.com/doc/1001004eg

实例代码请看源代码
vue实例-保险列表

01背包问题基础

编 写: zhangyue
时 间: 2016-12-27
说 明: 利用背包问题解决红包使用问题

一 01背包问题

    01背包问题是指在一个容量大小固定为M的背包中,装入体积和价值不同的宝石,怎么选择才能在背包中得到最大的价值。

二 动态规划

动态规划是指
        通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以一种循环的方式去解决。
        通常基于一个递推公式和一个或多个初始状态,当前子问题的解由上一个子问题的解推出。
        有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最        好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线
        
        状态转移方程:
            d(N,M) = max(d(N-1,M), d(N-1, M-weight(i)) + value(i));
            d(N,M) 有容量为M的背包,有N个宝石
            d(N-1,M) 当前的宝石不放入背包,所能获取的最大价值
            d(N-1, M-weight(i)) + value(i) 当前宝石放入背包,所能够获取的最大价值

三 代码

function getResult($bagItems, $bagSize) {
        var result = array();
        //生成状态数组
        foreach ($i = 0; $i < $bagSize; $i ++) {
            foreach ($j = 0; $j < count($bagItems); $j ++) {
                if ($bagItems[$j]['weight'] > $i) {
                    //当前重量大于当前背包总重量
                    if (j != 0) {
                        $result[$j][$i] = $result[$j-1][$i];
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = 0;
                    }
                } else {
                    //当前重量小于背包,可以放入背包
                    if ($j != 0 ) {
                        $tmp_value = $result[$j-1][$i - $bagItems[$j]['weight']] + $bagItems[$j]['weight'];
                        $result[$j][$i] = max($result[$j-1][$i], $tmp_value);
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = $bagItems[$j]['weight'];
                    }
                }
            }
        }

        //根据得到的状态得到所选的数组
        $return  = array();//存储放回的组合
        $cur_size = $bagSize;//当前红包容量
        for ($n = count($bagItems); $n >= 0 ; $n--) {
            if ($cur_size == 0) {
                break;
            } 

            if ($n == 0 && $bagItems[$n]['weight'] < $cur_size) {
                $return[] = $bagItems[$n]['id'];
                break;
            }

            if ($bagItems[$n][$cur_size] - $bagItems[$n-1][$cur_size - $bagItems[$n]['weight']] == $bagItems[$n]['weight']) {
                //判断当前的这个商品是不是在最优解里,如果不在则不放入
                $return[] = $bagItems[$n]['id'];
                $cur_size = $cur_size - $bagItems[$n]['weight'];
            }
        }

        //得到结果
        return $return;

    }

四 递推表格

函数得到的递推表格和最终最优结果:
体积 价值 0 1 2 3 4 5 6 7 8 9 10 11
4 4 0 0 0 0 4 4 4 4 4 4 4 4
5 5 0 0 0 0 4 5 5 5 5 9 9 9
6 6 0 0 0 0 4 5 6 6 6 9 10 11
解释: 1 表格是从上到下,即4-6,从左到右,即0-11生成的 2 第一行的意思:代表在0-11的背包容量下,只有一个体积为4价值为4的宝石时,所能获得最大容量 3 第二行的意思:代表在0-11的背包容量下,有一个体积为4价值为4和体积为5价值为5的两块宝石时,所能获得最大容量 4 第三行的意思:代表在0-11的背包容量下,有一个体积为4价值为4,体积为5价值为5,体积为6价值为6的三块宝石时,所能获得最大容量 5 最终结果:[6,11] = 11 这个最优解。

五 红包问题

使用红包时,只需要将价值和体积都类比于红包的金额即可,这样可以选出最后得到的红包使用组合。
存在问题:
    1 红包会涉及小数的问题,红包现在只保留两位小数,最简单的方法是给红包*100,这样会增加递推数组的大小,增加空间复杂度
    2 红包还存在过期时间,可考虑如何加上过期时间这一条件
    3 由于红包价格和体积是同一个值,可考虑简化算法

用户系统演进

用户系统演进.ppt

编   写:袁 亮
时   间:2016-12-21
说   明:用户系统演进

一、用户系统限制因素
    1、使用域名
        单个域名
        多个域名
    2、使用系统是单服务器还是多服务器
    3、使用域名是否属于同一个域名的不同子域名
    4、系统访问环境
        PC浏览器
        是否兼容IE浏览器
        是否兼容手机浏览器
    5、用户数据库是否唯一
        单一用户数据库
        多个用户数据库
        
二、单用户中心,单域名
    1、条件限制
        1.1 单个域名
        1.2 单一用户数据库
    2、实现方案
        2.1 session
            磁盘IO 
            多服务器session共享
        2.2 cookie
            域名,端口,路径,cookie名
            数据签名
            大小限制
            敏感信息
    3、其他
        3.1 可以有多种登陆方式
        3.2 可以接入很多种第三方登陆
        
三、单用户中心,单个根域名
    1、条件限制
        1.1 单个用户数据库
        1.2 多个域名同属于某个根域名
    2、实现方案
        2.1 cookie共享 (育儿网)
            a. cookie设置在根域名
            b. 所有子域名都可以正常读取并验证签名
            c. 不可扩展,安全性无保障
        2.2 token形式 (共享session机制的变种)
            a. cookie设置在根域名
            b. 子域名读取到cookie之后,调用用户中心接口获取用户数据
            c. 将用户数据写入当前域名下
            
四、单用户中心,多个根域名
    1、条件限制
        1.1 单个用户数据库
    2、实现方案
        2.1 单点登陆 jsonp方式跨域 (淘宝)
            a. 统一的登陆,查收ticket
            b. jsonp方式将ticket循环传递给所有业务
            c. 业务域名根据ticket获取用户信息设置登陆
            d. 退出同样方式处理
            缺点:
                ios下,浏览器默认禁止第三方域名cookie设置,直接歇菜
        2.2 单点登陆 cas方式 (新浪)
            a. 通过jsonp+ajax+iframe的方式,在各个子域名框用户中心登陆
            b. 
            缺点:手机浏览器对iframe支持的很差
        2.3 服务端ticket形式,jsonp形式单点登录的变种
        
五、多用户中心
    1、条件限制
        无
    2、实现方案
        2.1 单域名或者多根域名跨域同三和四
    3、额外增加处理
        3.1 统一跳转地址
        3.2 用户聚合统一
        3.3 平台信息维护
        3.4 vtoken登录

linux定时任务的设置 crontab

一、基本使用
#分 时 日 月 周
* * * * * /home/blue/do/rsyncfile.sh

二、语法
crontab [-u username] [-l|-e|-r]
选项与参数:
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作排程;
-e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容 (备份)
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑

三、crontab的限制
/etc/cron.allow:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;
/etc/cron.deny:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab 。

以优先顺序来说, /etc/cron.allow 比 /etc/cron.deny 要优先, 而判断上面,这两个文件只选择一个来限制而已,因此,建议你只要保留一个即可, 免得影响自己在配置上面的判断!一般来说,系统默认是保留 /etc/cron.deny ,你可以将不想让他运行 crontab 的那个使用者写入 /etc/cron.deny 当中,一个帐号一行!
crontab3

四、crontab的原理
crond服务的最低侦测限制是分钟,所以cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容,因此,只要你编辑完 /etc/crontab 这个文件,并且将他储存之后,那么 cron 的配置就自动的会来运行了!

执行脚本的用户:/var/spool/cron/
执行记录:/var/log/cron
crontab2

五、crontab 的格式

代表意义 分钟 小时 日期(天) 月份 周 命令
数字范围 0-59 0-23 1-31 1-12 0-7 执行的命令
周的数字为 0 或 7 时,都代表『星期天』的意思!

辅助字符

特殊字符 代表意义
*(星号) 任何时刻
,(逗号) 代表分隔时段
-(减号) 代表一段时间范围内
/n(斜线) 代表每隔n单位间隔

六、周与日月
周和日月不是 并 的关系,而是 或 的关系。

你可以分别以周或者是日月为单位作为循环,但你不可使用「几月几号且为星期几」的模式工作。
30 12 11 11 5 root echo "just test" <==这是错误的写法
本来你以为十一月十一号且为星期五才会进行这项工作,无奈的是,系统可能会判定每个星期五作一次,或每年的 11月 11 号分别进行。

测试:(12月8号为星期4)
25 18 08 12 4 (echo "just test1" >> /tmp/test.txt ) //执行一次
25 18 07 12 4 (echo "just test2" >> /tmp/test.txt ) //执行一次
25 18 08 12 5 (echo "just test3" >> /tmp/test.txt) //执行一次

七、& 后台执行命令
1. command & : 后台运行,你关掉终端会停止运行
2. nohup command & : 后台运行,你关掉终端也会继续运行

参考:http://www.cnblogs.com/lwm-1988/archive/2011/08/20/2147299.html

八、2>&1 含义
先看一个例子:
0 2 * * * echo "just test" >> /tmp/test.txt 2>&1 &
这句话的意思就是在后台执行这条命令,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null 文件,也就是清空。

注释:
数字的含义:
0表示 键盘输入
1表示 标准输出
2表示 错误输出
>>是追加内容
> 是覆盖原有内容

示例:
0 2 * * * sh /tmp/test.sh 1>/tmp/out.file &
0 2 * * * sh /tmp/test.sh 2>/tmp/out.file &
0 2 * * * sh /tmp/test.sh 2>/tmp/out.file 2>&1 &
1、将tesh.sh 命令输出重定向到out.file, 即输出内容不打印到屏幕上,而是输出到out.file文件中。
2、2>&1 是将错误输出重定向到标准输出。 然后将标准输入重定向到文件out.file。
3、&1 表示的是文件描述1,表示标准输出,如果这里少了&就成了数字1,就表示重定向到文件1。
4 、& :后台执行

测试:
ls 2>1 : 不会报没有2文件的错误,但会输出一个空的文件1;
ls xxx 2>1: 没有xxx这个文件的错误输出到了1中;
ls xxx 2>&1: 不会生成1这个文件了,不过错误跑到标准输出了;
ls xxx >out.txt 2>&1 == ls xxx 1>out.txt 2>&1: 因为重定向符号>默认是1,这句就把错误输出和标准输出都传到out.txt 文件中。

九、注意点:2>&1写在后面的原因
格式:command > file 2>&1 == command 1> file 2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。

如果改成: command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但错误输出仍然保持在终端。
crontab1

微信支付成功后推荐关注栏目规则

QQ图片20161129172427

官网QA:
1.刷卡支付默认有推荐关注;
2.公众号支付和扫码支付需要5元以上才有推荐关注;(0.01就有推荐栏,第一次5元以上默认选中)
3.APP支付默认没有,需要申请配置,需要有一定用户规模才可以申请;
4.已经关注的不展示推荐栏
5.服务号未设置头像的在IOS不展示推荐关注栏;
6.用户取消过关注的默认不勾选;
7.服务商模式的,需要在特约商户开发配置页设置推荐关注APP id;
8.订阅号目前是不会有默认推荐关注的;
9.对于粉丝数大于 50W的公众号,有消息链接,朋友圈链接,公众号发起的jsapi支付场景,支付成功后不默认勾选关注。

客服说明:
微信支付后默认选中关注微信公众号需要的额外条件
1、第一次消费
2、消费金额需要5元以上

JSONP

JSONP是什么

跨域资源共享(Resources Domain Resources Sharing),客户端从不同的域名发送JSON响应时绕过浏览器限制

JSONP原理解析

利用 script标签 的 src属性 进行跨域请求,服务器响应函数调用传参。

2.1 静态方法创建

代码:

<?php
 //echo "a = 1";
?>
//html代码
<script type="text/javascript" src="http://ly.yungou.ws/test/index"></script>
<script type="text/javascript">
    console.log(a);   // 1
</script>

跨域请求成功!

2.2、 动态方法创建

动态创建 script标签的方式,添加到头部,来获取变量参数

<?php
    echo "var a = 1;";
 ?>

//通过 script语句动态创建 script标签进行请求
<script type="text/javascript">
   var script = document.createElement('script');
   script.src = 'http://ly.yungou.ws/test/index';
   var head = document.getElementsByTagName('head')[0];
   head.appendChild(script);
   console.log( a );
</script>

注意:原来动态创建 script 的方式发送请求 是异步的,虽然请求成功了,但是在使用变量时,请求还没有完成,相当于还没有定义变量,然后就报错了。
解决办法:使用callback

<?php
    echo 'callback(123)';
 ?>

<script type="text/javascript">
    var script = document.createElement('script');
    script.src = 'http://ly.yungou.ws/test/index';
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);

    function callback(data){
        console.log( data );    //callback(123) 对 callback 调用 输出 123
    }
</script>

那我们就可以用这种动态的方式 很轻松的 拿到后台数据了,只不过前台声明的和 后台 调用的 函数名 需要一样才行,如上面的 然而这样也不太好,每次改动,那都要前后台对接一下。

所以我们可以把回调函数名放在参数中传输。案例如下:

<?php
$callback = $_GET[ 'callback' ];    // get 通过 callback键 得到 函数名
$userInfo = array( 'username' => 'leiyuan', 'password' => '123456' );// 生成数据
$data = json_encode($userInfo);
echo "{$callback}({$data});";// hello( json_encode($arr) )

通过 script语句动态创建 script标签进行请求

    var script = document.createElement('script');
    script.src = 'http://ly.yungou.ws/test/callback?callback=hello';
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);
     function hello(data){
        console.log(data);// Object {username: "leiyuan", password: "123456"}        
    }
  </script>

2.3 jsonp原理:

JSONP是一个协议(并且是非正式传输协议)。 该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了.
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求,

2.4 jsonp原理

首先在客户端注册一个callback, 然后把callback的名字传给服务器。
服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

JSONP和JSON的区别:
目前为止最被推崇或者说首选的方案还是用JSON来传数据,靠JSONP来跨域。
  JSON(JavaScript Object Notation)和JSONP(JSON with Padding)
JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。一个是描述信息的格式,一个是信息传递双方约定的方法。
  1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery等框架都把jsonp作为ajax的一种形式进行了封装;
  2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加
```

JSONP使用注意事项
1、跨系统跨域名,获取基本信息,
ps:后端不能存在任何页面跳转登陆信息,否则会请求失败
2、jsonp的缺陷:不提供错误处理(对方拒绝请求,网络不通,请求地址或者参数不正确等等)如果动态插入的代码正常运行,你可以得到返回,但是如果失败了,那么什么都不会发生。
3、动态请求,都是异步请求。不支持同步请求,async无效。
请求不是通过XHR完成的,而是动态创建script标记,并请求url。跨域请求和dataType: "jsonp" 本身不支持同步操作。
4、若要在fun中使用jsonp请求后的参数,需要注意的是执行顺序,fun需要写在callback中才能成功调用参数。
5、如果没有定义jsonp和jsonpCallback,jsonp默认为"callback",jsonpCallback会是Jquery自动生成的函数名。
6、请求返回的是script tag,首先会调用jsonpCallback函数,不管是否找到该函数,都会调用success函数

参考资料

http://api.jquery.com/jQuery.ajax/

vuejs基础

整   理:肖雅君

时   间:2016-11-18

说   明:vue.js的安装、基本用法

官网:http://vuejs.org.cn/

1.安装
安装npm,建议安装cnpm,超超快速。
淘宝镜像:npm install -g cnpm --registry=https://registry.npm.taobao.org
安装vue:npm install -g vue-cli【cnpm install -g vue-cli】

2.初始化:
vue init webpack vueTest
[项目类型]-如:使用webpack这个模板,进行压缩和打包

依次输入:项目名
项目描述
项目开发者
是否使用语法检测工具
是否进行单元测试
是否进行集成测试

3.下载依赖:cnpm install
下载完毕后,打开项目,一般所需修改的页面文件在src文件夹下,打开package.json文件,能看到我们在初始化项目的时候,输入的项目名、开发者等信息,如下图:
6

其中src文件夹下有个component文件夹,是专门安置自己封装的组件,引用这些组件的时候,直接在src文件夹下app.vue中引入,如下图:
7

4.在项目文件夹下运行项目:npm run dev
注:需要npm的版本在3.0.0,否则error。
升级npm:npm -g install nom@3.0.0 [用npm依旧是等待很长时间没反应,用cnpm很快]
1
升级完成后运行,浏览器自动跳转到8080端口打开测试页:
2

5.项目的页面是src文件下的 app.vue,修改这个文件夹即可。
另,后缀是.vue文件,在用brackets 或者sublime软件编辑的时候,需要安装对应的插件,才可显示高亮。
brackets vue插件:http://brackets.dnbard.com/extension/brackets.vue
sublime vue 插件: Vue Syntax highlight/Jade

6.重要指令:
new 一个vue对象时,可以设置:
(1)对象的属性:
数据:data
方法:method
监听:watch
new Vue()对象,注意大小写。new vue()无效。
(2)关联:
模板html页面和vue对象的粘合,用模板指令v-text、v-html进行数据渲染
(3)控制显示和隐藏:v-if、v-show
v-if通过控制dom结构控制显隐。v-show:控制css样式的display来控制显隐。
(4)循环渲染:v-for
(5)事件绑定:v-on
<button v-on:click = "doThis"></button>
简写:
<button @click = "doThis"></button>
(6)属性绑定:v-bind
<img v-bind:src="imageSrc" :class="{ red: isRed }"/>

7.基本功能和应用:
(1)数据的双向绑定
(2)v-show和v-if的使用
(3)事件处理
(4)组件化方法
(5)代码逻辑或者业务逻辑的输出处理:computed
(6)列表输出
(7)组件化综合应用:列表输出 + 组件化结合
(8)添加任务总数和删除任务
(9)jquery 、ajax 和vue的结合
(10)vue-resource插件的使用

8.代码demo
(1)数据的双向绑定

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>{{myhead}}</h1>
    <h1 v-text="mytext"></h1>
    <input type="text" v-model="mytext" />
    <!--打印出data里的代码,测试双向绑定过程-->
    <pre>
            {{$data | json}}
    </pre>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            myhead:'你好!',
            mytext:'My name is Michellya!'
        }
    });
</script>
</body>
</html>

(2)v-show和v-if的使用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
    <h1>{{myhead}}</h1>
    <h1 v-text="mytext"></h1>
    <p v-if="!mytext">警告:请填写内容!</p>
    <input type="text" v-model="mytext" />
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            myhead:'你好!',
            mytext:''
        }
    });
</script>
</body>
</html>

(3)事件处理

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
    <button @click="mysubmit">submit</button>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            myhead:'你好!',
            mytext:''
        },
        methods:{
            mysubmit:function(){
                alert(11);
            }
        }
    });
</script>
</body>
</html>

(4)组件化

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
<!--组件化:1.自己定义组件-->
    <mylabel mychoice="赞" bgcolor="red"></mylabel>
    <mylabel mychoice="嘘" bgcolor="blue"></mylabel>

<!--2.用h5的新标签template  组件封装——应用1:类似微博的喜欢、不喜欢的点选计数-->
    <template id="choice-model">
        <h3>{{mychoice}}</h3>
        <button @click="num += 1" style="background:{{bgcolor}}">{{num}}</button>
    </template>        
</div>

<script>
    Vue.component('mylabel',{
        template: '#choice-model',
        props:['mychoice','bgcolor'],
        data:function(){
            return {num : 0}
        }
    });

    new Vue({
        el: '#app',
    });
</script>
</body>
</html>

(5)代码逻辑或业务逻辑的输出处理:computed

应用1:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
<!--        level {{level <= 100 ? '普通会员' : 'VIP会员'}}  -->

    level {{level}}
</div>

<script>
/*
    new Vue({
        el: '#app',
        data: {
            points: 200,
            level: '普通会员'
        }
    });
*/
    new Vue({
        el: '#app',
        data: {
            points: 200,
        },
        computed:{
            level:function(){
                if(this.points <= 100){
                        return '普通会员';
                }
                return 'VIP会员';
            }
        }
    });
</script>
</body>
</html>

应用2:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
    用户名:{{username}}
    <br/>
    <input type="text" v-model="first" />
    <input type="text" v-model="second" />
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            first: 'Michelle',
            second: 'yajun',
        },
        computed:{
            username:function(){
                return this.first + ' ' + this.second;
            }
        }
    });
</script>
</body>
</html>

(6)循环列表输出

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
    <ul>
<!--                <li :class="task.completed ? 'mydone' : '' " v-for="task in tasks">{{task.body}}</li>-->
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in tasks"
                @click = "toggleclick(task)">{{task.body}}</li>
    </ul>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            tasks:[
                 {body:'sleeping',completed:false},
                 {body:'shopping',completed:true},
                 {body:'swimming',completed:true},
                 {body:'running',completed:false},
            ]
        },
                methods:{
            toggleclick:function(task){
                task.completed = !task.completed;
            }
        }
    });
</script>
</body>
</html>

(7)组件化list综合应用:todo应用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
    <mytask :list="tasks"></mytask>
    <mytask :list="[{body:'唱歌',completed:true},{body:'跳舞',completed:false},]"></mytask>
    <mytask :list="tasks"></mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">{{task.body}}</li>
    </ul>
</template>
</div>

<script>
Vue.component('mytask',{
        template: '#mytask-model',
        props: ['list'],
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            }
        }
    });

    new Vue({
        el: '#app',
        data: {
            tasks:[
                {body:'sleeping',completed:false},
                {body:'shopping',completed:true},
                {body:'swimming',completed:true},
                {body:'running',completed:false}
            ]
        }
    });
</script>
</body>
</html>

(8)添加任务总数、删除任务和添加任务

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">     
    <mytask :list="tasks"></mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <h1>My Task <span v-show="remaining">({{ remaining}})</span></h1>
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">{{task.body}}
                <strong @click="deleteTask(task)">点我删除</strong>        
        </li>        
    </ul>
</template>
</div>

<script>
    Vue.component('mytask',{
        template: '#mytask-model',
        props: ['list'],
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            },
            deleteTask:function(task){
                this.list.$remove(task);
            }
        },
        computed:{
            remaining:function(){
                return this.list.filter(function(task){
                    return ! task.completed;
                }).length;
            }
        }
    });

    new Vue({
        el: '#app',
        data: {
            tasks:[
                {body:'sleeping',completed:false},
                {body:'shopping',completed:true},
                {body:'swimming',completed:true},
                {body:'running',completed:false}
            ]
        }
    });
</script>
</body>
</html>

(9)jquery 、ajax 和vue的结合
3

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
        
    <mytask>{{ $task }}</mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <h1>My Task <span v-show="remaining">({{ remaining}})</span></h1>
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">@{{task.body}}
                <strong @click="deleteTask(task)">点我删除</strong>        
        </li>        
    </ul>
</template>
</div>
<script src="http://vuejs.org.cn/js/vue.js"></script>
<script src="http://file2.ci123.com/ast/js/jquery_172.js"></script>
<script>
    Vue.component('mytask',{
        template: '#mytask-model',
        //创建一个空list数组
        data:function(){
            return {
                list:[]
            }
        },
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            },
            deleteTask:function(task){
                this.list.$remove(task);
            }
        },
        computed:{
            remaining:function(){
                return this.list.filter(function(task){
                    return ! task.completed;
                }).length;
            }
        },
        create:function(){
           $.getJSON('api/...',function(data){
                this.list = data; 
            })
        }
    });

    new Vue({
        el: '#app'
    }
});
</script>
</body>
</html>

(10)vue-resource插件的使用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
        
    <mytask></mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <h1>My Task <span v-show="remaining">({{ remaining}})</span></h1>
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">@{{task.body}}
                <strong @click="deleteTask(task)">点我删除</strong>        
        </li>        
    </ul>
</template>
</div>

<script src="http://vuejs.org.cn/js/vue.js"></script>
<script src="https://github.com/vuejs/vue-resource"></script>

<script>
    Vue.component('mytask',{
        template: '#mytask-model',
        data:function(){
            return {
                list:[]
            }
        },
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            },
            deleteTask:function(task){
                this.list.$remove(task);
            }
        },
        computed:{
            remaining:function(){
                return this.list.filter(function(task){
                        return ! task.completed;
                }).length;
            }
        },
        create:function(){
            this.$http.get('api/...',function(){

            })
        }
    });

    new Vue({
        el: '#app',
    });
</script>
</body>
</html>

9.强荐浏览器插件:vue-devtools
作用、操作及下载:http://www.cnplugins.com/devtool/vuejs-devtools/
插件:
4
界面:
5

Json的使用

一、简介
JSON:JavaScript 对象表示法
JSON 是存储和交换文本信息的语法。类似 XML。
JSON 比 XML 更小、更快,更易解析。
JSON的媒体类型被定义为 application/json,而文件的后缀为.json。

二、应用
JSON的应用
1、接口
2、微信开发

XML的应用
1、我们一般用于sitemap较多
2、xmlrpc是使用http协议做为传输协议的rpc机制,使用xml文本的方式传输命令和数据。
备注:json和XML可以互转

和JavaScript

一、JSON - 转换为 JavaScript 对象
1、能够使用内建的 JavaScript eval(string)方法进行解析
原因:JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。
由于这种相似性,无需解析器,JavaScript 程序能够使用内建的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象。

ajax返回的是字符串,而不是json对象。
data = eval('('+data+')');

二、实例
var JSONObject=
{
"name":"Bill Gates", "street":"Fifth Avenue New York 666", "age":56, "phone":"555 1234567"
};

JSONObject.name //调用
三、语法规则
数据在名称/值对中
数据由逗号分隔
花括号保存对象
方括号保存数组
值/对象/数组

四、方法
1、JSON.parse()
parse用于从一个字符串中解析出json对象

例子:
var str = '{"name":"huangxiaojian","age":"23"}'
结果:
JSON.parse(str)
Object
age: "23"
name: "huangxiaojian"
proto: Object

2、JSON.stringify()
stringify()用于从一个对象解析出字符串

例子:
var a = {a:1,b:2}
结果:
JSON.stringify(a)
"{"a":1,"b":2}"

五、错误提示
1、
1
data不是正确的json格式,造成解析出错
2、
2

var a=JSON.parse('{"a":"aaaaa"}');//正确
var a=JSON.parse("{'a':'aaaaa'}");//错误

3、 Uncaught TypeError: Cannot use 'in' operator to search for '' in JSON string
解决方案:JSON字符串转换为JavaScript对象。
要修复它,通过标准JSON.parse()或jQuery 的 $.parseJSON 将其转换为JavaScript对象。
4、
4
var a = { };
var b = { a: a };
a.b = b;
JSON.stringify(a);

参考:https://segmentfault.com/a/1190000002532027

php中的json
一、注意点
1、json_last_error:返回最后发生的错误
2、json_decode 当第二个参数为 TRUE 时,将返回 array 而非 object 。
3、由于json只接受utf-8编码的字符,所以json_encode()的参数必须是utf-8编码,否则会得到空字符或者null。

4、PHP支持两种数组,一种是只保存"值"(value)的索引数组(indexed array),另一种是保存"名值对"(name/value)的关联数组(associative array)。
由于javascript不支持关联数组,所以json_encode()只将索引数组(indexed array)转为数组格式,而将关联数组(associative array)转为对象格式。
$arr = array('one', 'two', 'three');
echo json_encode($arr); //["one","two","three"]

$arr = array('1'=>'one', '2'=>'two', '3'=>'three');
echo json_encode($arr); // {"1":"one","2":"two","3":"three"}
数据格式从"[]"(数组)变成了"{}"(对象)。
如果你需要将"索引数组"强制转化成"对象",可以这样写
echo json_encode((object)$arr);
echo json_encode($arr,JSON_FORCE_OBJECT )

5、类的转换

{     
  "public_ex": "this is public" 
 }

除了公开变量(public),其他东西(常量、私有变量、方法等等)都遗失了。

二、错误
  $json = "{ 'bar': 'baz' }";      //分割符只能用单引号  
$json = '{ bar: "baz" }';        
$json = '{ "bar": "baz", }';

二、中文编码的问题
1、
function getJson($data){
if(version_compare('5.4',PHP_VERSION,'<')){
//5.4以上
return json_encode($data,JSON_UNESCAPED_UNICODE);
}else{
return urldecode(json_encode(url_encode($data)));
}
}

数据存的json格式,如果数据库存的是array
eval("\$session= $str;");

三、json格式的问题
微信放的json解析不了:
去除反斜杠 StripSlashes

其他补充:
json的校验
一个文本文档或字符串必须遵守JSON的语法定义,才能被视作一个有效的JSON文档。
http://www.jsonlint.com/
补充:
用 JSON 构建 API 的标准指南中文版
http://jsonapi.org.cn/