JSON Web Token(JWT)

JWT是一个开放的标准(RFC 7519),定义了一种紧凑,自包含的方式使用json对象来安全的传递信息。这些信息可以验证和信任,因为是通过HMAC或者RSA等算法做数字签名的。

JWT 特点

  • 体积小,因而传输速度快
  • 传输方式多样,可以通过URL/POST参数/HTTP头部等方式传输
  • 严格的结构化。它自身(在 payload 中)就包含了所有与用户相关的验证消息,如用户可访问路由、访问有效期等信息,服务器无需再去连接数据库验证信息的有效性,并且 payload 支持为你的应用而定制化
  • 支持跨域验证,可以应用于单点登录。
阅读全文 »

神经学家塔拉·斯瓦尔特(Tara Swart) 博士在《快公司》(Fast Company)网站发表的一篇文章中说,从事脑力工作的人通常不会像运动员那样,认真对待自己的每一餐,这种做法是错误的,大脑需要适当地补给才能以最佳状态运转。斯瓦尔特博士分享了5个能让大脑达到最佳状态的补给建议:

阅读全文 »

PB9调用dll的时候问题比较怪异,同样的代码在xp下面使用vs2010编译就可以了。
在win7下面使用vs2015编译出来就不行。注:已经设置支持xp了。

使用def导出接口

Module-Definition File (.def)

VERSION major[.minor]

LIBRARY "dllName"

EXPORTS
merchantBind @1

引用DLL

静态方式

#include "..\\xxx\xxx.h"

#ifdef _DEBUG
#pragma comment( lib,"..\\debug\\xx.lib" )
#else
#pragma comment( lib,"..\\release\\xx.lib" )
#endif

动态方式

进程调用 LoadLibrary(或 AfxLoadLibrary)以显式链接到 DLL

C#调用win32 Dll

参考文章
msdn marshal api
C++ DLL的返回值,安全的做法是分配一个全局 char 数组,把要返回的 char * 复制到这个 char 数组中,

class demoClass
{
[DllImport("demo.dll", EntryPoint = "demo_getVersion", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr demo_getVersion();

[DllImport("demo.dll", EntryPoint = "demo_fun1", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr demo_fun1(string param);


public static string getVersion()
{
IntPtr intPtr = demo_getVersion();
string result = Marshal.PtrToStringUni(intPtr);
return result;
}

public static string merchantScanBarcodePay(string param)
{
IntPtr intPtr = demo_fun1(param);
string result = Marshal.PtrToStringUni(intPtr);
string ss = result;
return ss;
}
}

C++ 接口
wchar_t* __stdcall demo_getVersion();
wchar_t* __stdcall demo_fun1(wchar_t* param);

c# 类型对照

一下操作在CentOS 7.4.1708上验证过
CentOS内置的Python版本还是2.6(甚至2.4.3),这用于应用显然是不合适的。
注:由于Linux系统很多方面都依赖Python,所以一般是不能直接替换版本的。
下面是如何下载和设置Python(2.7.6和3.3.3)而不破坏内置的2.6(或2.4)版本的Python

阅读全文 »

使用 sqlalchemy 有3种方式:
方式1, 使用raw sql;
方式2, 使用SqlAlchemy的sql expression;
方式3, 使用ORM.
前两种方式可以统称为 core 方式.

阅读全文 »

  1. 创建flask虚拟环境
    conda create --name gisPy36 python=3.6
    source activate gisPy36
  2. 安装flask,和相关扩展
    pip install flask
    数据库操作,这个是py3的库,配置及相关操作参考flask学习笔记-数据库相关
    pip install PyMySQL
    数据库ORM扩展包
    pip install flask-sqlalchemy
    数据库迁移扩展包
    pip install flask-migrate
    使用bootstrap
    pip install flask-bootstrap

    暂时不使用JWT,因为涉及的知识点太多,花的时间比较多。
    JWT登录验证,这里先使用PyJWT 1.4.0,后面在看看flask-jwt扩展
    pip install PyJWT

jsonify返回一个Response对象,可以用来设置cookie

项目结构:
使用Blueprint来规划。
两点需要注意的地方:

  1. 路由装饰器由Blueprint提供。下面是举例
    @main.app_errorhandler(404)
    def page_not_found(e):
    return render_template('404.html'), 404
  2. url_for的使用略有不同
    默认Blueprint会带有一个命名空间,就是构造函数的第一个参数。如果命名空间是mian,那么index的注册端点是main.index。
    其URL使用url_for(‘main.index’)获取。如果是当前Blueprint可以省略空间名写成url_for(‘.index’)。否则必须带有空间名

g环境变量

需要导入
from flask import g
添加属性并赋值
g.name = 'John'
获取属性
name = g.get('name','no name')
判断属性是否存在
if hasattr(g, 'needLogin'):
...

返回模板和cookie

resp = make_response(render_template("index.html", cls='ShowLoginModal'))
return resp

日志处理

import logging
from logging.handlers import RotatingFileHandler

# 1024*1024*10
handler = RotatingFileHandler('emails.log', encoding='UTF-8',maxBytes=1024*1024*10,backupCount=50)
handler.setLevel(logging.DEBUG)
# logging的级别主要有NOTSET、DEBUG、INFO、WARNING、ERROR和CRITICAL
logging_format = logging.Formatter(
'%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
handler.setFormatter(logging_format)
app.logger.addHandler(handler)

获取当前项目路径

curPath = os.path.split(os.path.realpath(__file__))[0]

查看版本

python -V

导出依赖包

requirements.txt可以通过pip命令自动生成和安装

生成requirements.txt文件
pip freeze > requirements.txt
安装requirements.txt依赖
sudo pip install -r requirements.txt
如果是虚拟环境下不需要使用sudo,否则会安装到系统路径下面的python里面

查看已安装包,升级

# 查看已安装的包
pip list
# 列出可升级的包
pip list --outdate
# 升级指定的包
pip install --upgrade requests // mac,linux,unix 在命令前加 sudo -H

环境管理

查看所有安装的环境
conda env list

基于python3.6版本创建一个名字为gisPy36的环境
conda create --name gisPy36 python=3.6

激活环境
source activate gisPy36

退出当前环境
source deactivate

删除该环境
conda env remove -n gisPy36

多版本时pip指定版本安装

安装setuptools包
pip install -t /usr/local/lib/python2.7/site-packages/ setuptools

有用的库

[pefile](https://github.com/erocarrera/pefile)获取pe文件相关信息,例如版本信息。跨平台的

[tabulate](https://pypi.python.org/pypi/tabulate)
# 格式化dataframe
print tabulate(df.head(5), headers='keys', tablefmt='psql')

控制台相关

想要print始终显示在同一行,本身是在最后加上逗号即可,即:
print "xxx",
然后又想要实现,新打印的一行,冲掉之前旧的一行,达到显示出下载文件大小一点点增加,但是却始终保持同行,那么就再打印的内容最后添加上\r即可:
print "xxx\r",

脚本的执行流程

浏览器输入一个URL地址,服务器找到所请求的文件(可以是多个)发送给浏览器。
浏览器加载文件显示给用户。
在加载文件的时候会解析html结构如果发现标记,就调用javaScript解释器执行标记块里面的脚本。
javaScript并不改变原来的html和css文件,他只是改变浏览器内存中页面的DOM表示
下面的脚本是当web夜幕文件准备就绪的时候执行相关的操作。

<script>
$(document).ready(...);
</script>

$符号是jQuery的简写方式。jQuery()简写为$(),这就是jQuery函数,主要任务是获取括号中指定的元素。元素可以是css选择器,javascript对象,html。

选择元素的方式

和CSS的选择器操作一样,CSS选择元素增加样式,javascript选择元素增加行为
注意:javascript的选择器采用字符串的形式。

元素选择器,隐藏所有h1元素
$("h1").hide();
类选择器使用.开始,所有my_class成员都向上滑动
$(".my_class").slideUp();
id选择器使用#开始,所有my_id的元素淡出。
$("#my_id").fadeOut();

举例:
$("#myTop").css({"background-color":"blue"});
把id为myTop的元素的css规则里面的背景色设置为蓝色。

$("span.Italian").toggle();
处理span里面的类为Italian的元素
<span class="Italian">test text</span>

$("p#mytext").show();
处理段落里面id为mytext的元素
<p id="mytext">test text</p>

类型+id选择
$("button#btn1").click(...);
$("button#btn2").click(...);

表示当前正在处理的元素,依赖于上下文。
$(this)

后代选择器, 左边是父元素,右边是子元素,中间有个空格
选择div元素中所有的p元素
$("div p")
类和ID选择器与后代选择器结合使用
选择div元素中id为my_id的p元素
$("div p#my_id")

页面事件

  1. 为元素绑定一个事件。
方法一,在页面加载时为元素增加事件
$("#myElement").click(function(){...});

方法二,可以在页面加载后为元素增加事件
$("#myElement").bind('click',function(){...});

这里方法一和二最明显的区别在于方法一只有在DOM已经存在时才可以使用。
对于代码中新创建的元素就只能使用方法二来增加事件。

整个浏览器都是事件型的。
浏览器事件:error,resize,scroll
键盘事件:keydown, keypress, keyup
表单事件: blur,change,focus,select,submit
文档加载: load,ready,unload
鼠标事件: click, hover, focusin, focusout,mouseout,mouseover..

  1. 删除一个事件
从myElement删除click事件
$("#myElement").unbind('click')
从myElement删除所有事件
$("#myElement").unbind()

迭代器each,遍历元素,为每个元素执行操作

$(".nav_item").each(function(){
$(this).hide();
});
  1. 代码触发事件

结合选择器使用.trigger方法

$("button:first").trigger('click');
$("form").trigger('submit');

  1. 函数
function name(){
code here
}

函数表达式

var myFunc2 = function(){
$("div").show();
}

function myFunc1(){
$("div").hide();
}

调用函数,这里需要括号
myFunc1();
作为处理函数调用时,函数不需要括号
$("#myElement").click(myFunc2);

匿名函数
也叫自执行函数,一旦在代码中遇到匿名函数就会立即执行。函数中的变量只有在运行时才可用。

条件判断语句,web事件

  1. 修改DOM

移除元素

remove 从DOM中删除
detach 从DOM中取出,但是还会维护,可以重新关联

向上选择使用parent方法,左右选择使用prev和next方法,向下选择使用children方法
可以使用方法链进一步查找。
$(".fish").parent().parent();

删除元素中的内容
$("p").empty();

使用parents方法遍历所有的父元素
使用siblings方法遍历兄弟元素
选择距离所选元素最近的父元素使用closest方法
$("li").closest("ul")

可以使用变量存储元素。用于删除和恢复,需要在变量钱添加$符号,类型是数组
$f = $(".fish").parent().parent().detach();

替换DOM元素,一对一替换可以使用
$("h2").replaceWith("<h1>My Menu</h1>");

多对一的替换分两步

  1. 把新类插入旧类后面,这里有before和after两个位置一前一后
  2. 删除旧类

使用过滤器缩小选择范围
first 第一个元素, last最后一个元素,eq根据索引选择

元素索引为1的元素
#(".menuList").children().qu(1);

slice切片选择元素
filter过滤选择
not过滤掉不匹配的元素

获取,修改元素文本

var realPay = $("#realPayment").text();
$('#moreTime').text("5年");

2017年年终总结

7c7c51ee.png fdb8c155.png a73cb930.png

季度总结

677d7d0a.png 31af670e.png