我们知道,小程序服务器的域名必须备案。然而,扫码签到工具的服务器在国外,没有备案,也没法备案。
小程序服务器不备案,我们是怎么做到的呢?答案就是代理。
下面对背景和解决方案逐一详细说明。
背景:
我们有境外的虚拟服务器,有域名,但域名没有备案(鉴于服务器在国外,没法通过备案)。
服务端使用的是Laravel框架。
网上提到了新浪的云应用解决方案。我们申请了php的服务器和一个二级域名,10元/月。这个二级域所在的一级域名已经备案,可以通过小程序的服务器域名校验。
当决定把服务器搬到新浪的服务器时,才发现新浪的php服务器不支持Laravel框架。
解决方案:
怎么办呢?
既然小程序和后端服务器之间的交互比较简单,都是通过Request交互(除了JSON格式的request,就是downloadImage),为什么不试试把新浪服务器作为一个代理,让它作为前端小程序和后端服务器之间的桥梁呢?
思路如下图所示:
怎样实现代理呢?
把所有的Request按照类型分类,让新浪服务器处理各种类型的Requeset。在当前案例中,我们使用了get、post、put、getDownImg这些类型(说明:getDownImg虽然是get请求,不过它返回的类型是二进制数据,不是JSON格式,所以和get分开处理),因此,在新浪服务器上创建get.php、post.php、put.php、getDownImg.php分别处理各自对应类型的request。
每个代理的内部实现是怎样的呢?
先看看小程序服务器处理的request。以get为例,request的格式如下:
https://webserver/path?param1=value1¶m2=value2
其中webserver表示服务器的地址,path表示API的名称,param1和param2分别是两个参数,value1和value2对应各自的参数值。
也就是说在第2步中,新浪服务器转发request到小程序服务器的格式应该如上所示。
为了保证通用性,新浪服务器接收到的request(第1步中的request),我们把path放到参数里,如下:
https://sinawebserver/get.php?method=path¶m1=value1¶m2=value2
然后从参数里提取出method的值,作为path转发(第2步中的request)到小程序服务器,这就是get.php做的事情。
当然,需要注意的是,既然我们在代理中使用了method这个参数,所以在小程序的服务器提供的API中,我们应该避免method参数,否则在get.php在处理请求的时候会引起冲突。
同样,回到小程序,发送请求的方式就稍微有点不一样了。
在使用代理之前,request的样例可能如下:
wx.request({ url: 'https://webserver/path', data: { x: '' , y: '' }, header: { 'content-type': 'application/json' // 默认值 }, success: function(res) { } })
使用代理之后,它就变成了如下:
wx.request({ url: 'https://sinawebserver/', data: { method: 'path' x: '' , y: '' }, header: { 'content-type': 'application/json' }, success: function(res) { } })
至于response,第3步中的response,通过新浪代理服务器,原封不动地返回给小程序就可以了,无需任何变动。
按照这种方法,我们写出其他几种类型的request代理,如post.php、put.php、getDownImg.php。
大功告成,我们的境外服务器可以为小程序提供服务了。
最后,还得说明,在这个方案中,我们增加了一个代理层,以致让系统的request反应链变长了,增加了系统的响应时间,也增加了潜在的不稳定性。
个人看法:如果有条件,不怕麻烦,还是建议申请国内的服务器,备案域名。
最后,附上新浪服务器作为代理服务器的php源代码,供大家参考。https://github.com/franczx/sina_proxy_4_wechat
请你留言