因为服务器上HTTP和HTTPS一起存在,所以分享接口这里出了一些问题。

在调用分享接口生成签名时,签名用的url必须是调用JS接口页面的完整URL,但因为存在http和https两种,而Django其实不知道客户端到底是访问http还是https,所以产生了问题。如果写死http, 则访问https时,微信分享签名出错;相反的,如果写死https, 则访问https时,微信分享签名会出错。有什么解决的办法?

查看request对象,知道scheme这个属性,于是看到SECURE_PROXY_SSL_HEADER设置。

大意就是当在settings里配置了SECURE_PROXY_SSL_HEADER,Django就会到request.META里读取相关参数,如果有设置https,则这是一个https请求。而相关参数需要代理服务器设置,我这里使用Nginx。

于是在Nginx配置里,当访问的是https时,就加上

1
proxy_set_header HTTP_X_FORWARDED_PROTO https;

然后在Django的settings配置里加上

1
SECURE_PROXY_SSL_HEADER = ('HTTP_HTTP_X_FORWARDED_PROTO', 'https')

这里之所以会多一个HTTP_是因为Django默认会给request.ME如此配置后,request.scheme就会返回http, 当请求是https时,则会返回https。分享的签名正确,问题得到解决。

联系作者

前几天同事推荐了djano-extensions,说是用来执行一些Django脚本特别爽,尝试之后,果然如此。

RunScript里有编写脚步的方法,有了它,之后写脚本时不需要导入Django环境,因为django-extensions帮你做了,很不错。

1
2
3
4
5
import os
import django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
django.setup()

联系作者

在PDF中需要添加签名信息,在网上找到
JSignPdf, 虽然两年多没更新了,但至少还能工作。

查看文档,发现美中不足的一点是只能一页一页的签名。

需要注意的一点是,图片必须是透明的,要不能签到PDF上会覆盖文字。

尝试之后,一个可行的签名如下

1
java -jar JSignPdf.jar -kp 111111 -ksf temp.pfx -llx 100 -lly 100 -urx 200 -ury 200 --bg-path Wechat2.png --l2-text '' -V 007_overview.pdf

参数的具体意义可以看文档。

联系作者

最近需要将Word文档转为PDF,正好在阿里云的同学做过,于是请教他,他给了一些参考资料,解决了转换的问题。

其中Jacob因为只能用于Windows平台,所以没有尝试。尝试了JODConverter之后,可以转换,效果还不错,暂定使用它。

只是还是存在一点乱码问题,之后再看看怎么解决。

代码博主已经开源,我把它放在了Github上,加上命令行输入,可以见这里,主要使用Apache的common-cli这个库。

之后是在Intellij IDEA导出jar包,参考
Idea 导出 jar包即可。主要步骤如下

1
2
3
4
5
6
7
8
9
10
11
(1)File→Project Structure...→Artifacts→+→jar→From modules with .... → 选择一个要执行的main方法

(2)extract to jar

(3)选择manifest的位置:d:\idea\myproject\src

(4)勾选build on make

(5)build -- make project, (如不行,在此之前,执行下mvn clean)

(6)D:\idea\myproject\out\artifacts\ 寻找jar

参考资料

联系作者

之前同事做微信公众平台的扫描带参数二维码事件时老是提示”该公众号暂时无法提供服务,请稍后再试”, 当时没有得到解决,现在好好看了文档,尝试之后,终于得到解决,记录下来。

被动回复用户消息里看到如下一段话

假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),否则,将出现严重的错误提示。详见下面说明:

1、(推荐方式)直接回复success

2、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)

一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:

1、开发者在5秒内未回复任何内容

2、开发者回复了异常数据,比如JSON数据等

1
2

看到这里推荐返回success, 而公司后台的api使用Django-REST-Framework,于是简单返回`return Response("success")`, 但还是一直报错,后来发现代码里写着

def get_renderers(self):
    if self.request.method == 'GET':
        return [TextRenderer()]
    return [XMLRenderer()]
1
于是将它注释掉试试,发现还是不行,默认情况下返回的使JSON字符串,于是将这个函数改为
def get_renderers(self):
    return [TextRenderer()]

```
错误消失了,问题解决。这里使用TextRenderer后,返回的格式是text/plain。

另外还发现一个问题, 生成带参数的二维码一共有两个文档, 文档1文档2, 一个有效期最长可以设置为在二维码生成后的7天,一个有效期最长可以设置为在二维码生成后的30天,真是蛋疼。

联系作者

最近从公司APP分享出去的一篇文章,访问量暴增,而访问计数直接访问的数据库,数据库产生行级锁,许多访问超时。

1
News.objects.filter(pk=self.object.id).update(view_num=F('view_num') + 1)

临时把访问计数去掉。之后找到Redis计数器。在访问文章时,使用incr自增。只是在访问文章列表时,如果对每篇文章都要读一次Redis会影响性能,于是只好做了延时处理,每个一段时间同步到数据库,并进行清零,等想到更好的解决办法再说。

清零时,最好不要使用set key 0这种用法,在多线程情况下会出问题,目前使用incrby key -view_num这种方式, 也就是减去目前Redis中浏览量的方式。

Redis确实是好东西,需要深入学习。

参考资料

联系作者

Django服务器的响应慢了, 想加上缓存。在网上查了之后,发现在queryset级别有3个选择。

  • django-cache-machine
  • johnny-cache
  • django-cachalot

最后选择了django-cachalot, 因为发现这个最靠谱。

安装后发现,目前的版本只支持Django1.8, 而1.2.1版本不支持缓存时间设置,也就是CACHALOT_TIMEOUT设置,而线上服务器的Django正好是1.7版本,于是只好放弃。

联系作者