如果你们开发团队正在使用PHP,并考虑迁移到Node.js,这篇文章很适合你。本文并不探讨从PHP移植到Node.js的细节,以及Node.js的基础知识。而是涵盖:决策制定、着手点的描述、编写 Node.js 服务器的深层次注意事项、以及部署策略。
为什么迁移?
1stdibs 决定从 Apache/PHP 迁移到 Node.js+Express 有五个理由:
代码更少
全栈式JS
开发人员幸福度更高
投入回报率
未来的优化
代码更少
1stdibs基于面向服务体系架构(SAO),前端调用后台的java服务。这意味着需要同时维护前端模型,以及服务端PHP和客户端JS模板。试想一下,如果可以摆脱PHP,就能够统一前端展现与后台模型于一种语言:JavaScript(同时可以合并一些模板)。从维护的角度来看,这么做代码更简洁,并且没有重复逻辑。
同构JavaScript万岁!
全栈式JS(及其优点)
整个开发栈使用一种语言很简便。对开发者来说,较少的环境切换使他们开心和高效。额外的好处是工具使用更简单。相比之前使用Composer和npm两个包管理器,现在只需要一个。尽管Composer很出色,由于nbp负责工具和客户端管理,nbp总是必要的。一旦去掉所有的PHP代码,nbp将成为仅有的包管理器。
开发人员乐意
我们要保证开发人员的技能集得到扩展、职业生涯不断发展,这一点很重要。对于JavaScript工程师而言,Node.js极具吸引力。能够在服务端使用与客户端相同的工具、风格和模式,是非常顺手和高效的。此外,Node.js相当流行,在企业级开发上也得到了长足发展。Node.js是JavaScript工程师的必备技能。
投入回报率
我们在招聘优秀的JS工程师和培训初级JS工程师方面花了大价钱。由于客户端栈很复杂,我们需要高级JavaScript工程师。我们不再雇用PHP工程师,仅仅雇用了JavaScript工程师。我们的观点是,为什么不培养他们在服务端的技能呢?
未来的优化
长远而言,我们打算把两个庞大的应用分割成一系列独立部署的小应用。这很容易通过Node.js、Express和nbp实现。理论上,PHP(比如使用Slim)可以做同样的事。但我们非但得不到上述好处,还会搞得一团糟:在Apache/PHP上进行操作会更加复杂,基础设施也会变得有些奇怪。
选择框架
那个最终被我们用Node.js替换掉的PHP应用,主要有如下职责:
登录和授权
路由选择和服务端模板引擎(服务HTML)
引导前端应用
代理服务(为了回避CORS)
服务静态资源(js,css,images)
这些就是我们需要替换掉的基本功能。
我们尝试过不少框架,Express令人叹为观止(试一下我们评估过的spreadsheet)。任何未基于Express 的框架看起来都不靠谱。Express通俗易懂,并有良好的文档。另外,可以招聘到正经培训过Express的人。
我们添加了一些kraken的核心模块(express-enrouten用于路由选择、lusca负责安全);此外,i18n-node提供国际化支持,模板引擎使用Swig(我们后来放弃了Swig。呵呵,开源软件还是有风险的)。
我们考虑过全盘使用kraken,但是从原来的服务端php模板引擎Twig切换到Swig直截了当,还很快捷。此外,kraken里面的Dust和i18n也不讨人喜欢。
编写服务器
选好了框架,下一步该写服务器了。
使用Apache+PHP时,你不需要再写一个服务器。Apache本身就是服务器,PHP是应用。如果使用Node.js,服务器和应用是同一个。从Apache/PHP转到PHP,你需要处理一些之前自然而然使用的功能,这一点很重要。使用Apache,你(或者系统管理员)配置服务器,在PHP应用里完全不用关心Apache为你处理的那些事。Node.js却以一种不同的方式来工作。
提供静态文件服务
毋庸置疑,提供静态文件服务是Apache的核心功能。Node.js与此不同,你要在应用中配置静态文件服务。幸运的是这很简单,有良好的文档说明,并且是在Express中实现的。
日志
很多基本的Apache配置为你提供访问日志和错误日志。使用Node.js时,估计你也猜到了,同样需要在应用中配置。所幸很多优秀的开源软件包使之变得很简单。Morgan是一个基本的请求日志记录器,它配置简单,允许你把日志写到输出流(标准输出设备或文件)。如果你需要把日志写到数据库,或者有别的(更高级的)日志需求,那就试一下winston吧。
代理
我们有一个基本需求:能够代理传输客户端ajax请求到后台服务。相比于处理CORS头,代理所有来自相同域的请求要简单得多。但你要想通过代理使用webpack-dev-server(正如我们所做的),就必须在Node.js应用中处理这一问题。http-proxy是一个简单可靠的解决方案。
剩下的工作
除了上面提到的,还有一些列别的工作需要完成。我们从一个MVC应用谈起,该应用基于 CodeIgniter(CI)框架,为一系列单页应用提供服务。大部分工作就是移植:
CI控制器移植到Express路由选择器和中间件(包括登录和认证)
Twig模板引擎移植到Swig(这一步比较琐碎)
Service层数据访问(以便正常启动客户端单页应用)
上面并未列出CodeIgniter模型这一关键组件。事实上根本不用重写PHP模型!太给力了!我们的客户端应用使用Backbone模型。当然这要扩展Backbone.Model.sync,从而使之全局地工作在服务器和客户端。
部署
如果你的app规模较大,不应该一次性全部上线。可以通过渐进式部署的方式逐步上线。我们因此花费了好几周。
渐进式部署的优点:
最小化bug范围
每次在发布一部分路由及功能的同时,其他工程师可以正常进行开发
对正在进行的功能开发和改进影响最小 — 新功能可以继续发布(这可能导致重复的工作)
如果操作得当,可以快速回滚到之前的服务
NGINX很不错
该如何逐步上线呢?我们在众多的服务器中挑选了Nginx。
1
2
3
4
5
+----------+
http | |--->
Apache/PHP
request---->| Nginx
|
| |--->
Node.js
+----------+
Nginx允许你一次只“打开”一个路由(如果发现情况不妙就关掉 — 正如我们多次遇到的),这给了你很大的自由度。我们也发现打开路由的时候不用部署代码,这很有帮助。这在一周一次的发布计划里,为我们提供了一些回旋空间。
不过有一个缺点,你需要确保客户端代码同时接受旧的Apache/PHP服务器和新的Node.js服务器提供的服务。这并不可怕,不过你要把旧服务器上未优化的功能移植到新的服务器。屏住呼吸去做吧(记得写一个便利贴去清理你的技术债)。
总结
从头到尾,整个移植工作大概花费了一年。这听起来可能有点荒谬,不过这个时间表包括决策过程(比较匆忙)、基于Express写一个满足需求的核心框架、移植所有功能、逐步渐进式上线。此外,请记住,我们始终只有一两个开发者为之工作 — 并且是兼职。
如果你想尝试一下,请慎重考虑。你的团队能否受益?你的整个组织能否受益?如果你来自商业组织,请记住商业需要持续运转。你需要在商业目标和工程目标之间找到良好的平衡。
❷ 手把手教你调用微信扫一扫!三分钟包会
这是我第一次公众号开发,本以为看着微信官方文档直接复制粘贴就好了,没想到是我天真了,爬过一个坑又入一个坑!就这么一个简单的事,竟然搞了一下午,所以写了这篇文章,希望可以帮到大家!
第一步:引入 weixin-js-sdk
直接在 html 文件内,使用 script 引入:
或者
第二步:权限验证配置
timestamp,nonceStr,signature 重要信息请根据自己的公众号信息去获取。需要注意的是 debug 调试的时候,设置为 true ,会自动弹出配置成功或失败信息,调试时可以借助它。
第三步:调用扫一扫接口
我们在需要的按钮处,点击事件处开始调用扫码接口,如:
做了一个判断处理,检查只有微信浏览器,其他浏览器不可以调用:
第四步:真机测试
真机测试的时候,一直在提示:
errMsg:config:invalid signature
中文叫做签名无效。
查找原因是因为我的签名获取来和官方 微信 js 接口签名校验工具获取来的数据不一样,很明显获取的签名有问题,是因为我的 url 配置和前端调起接口的 url 不一致造成的。
第五步:苹果手机测试
苹果手机真机测试,提示错误信息为:
the permission value is offline verifying
翻译为中文:权限值正在脱机验证
这个错误原因是 config 没有正确执行。
又继续去检查签名的问题,最后发现是后台接口字段写错了,欲哭无泪,总之还是签名信息错误。
第六步:安卓正常,苹果点击无反应
用安卓测试的时候,竟然好了,完美展示扫码结果,以为要好了。使用 ios 测试的时候,竟然发现点击的时候没有任何反应。
找了半天原因,是因为 window.location.href 不同造成的。
测试结果:
安卓:https://hp.******.net/
IOS:https://hp.******.net//
IOS 手机就是因为 url 与签名配置处的 url 不同,所以导致 config 执行失败。究其原因是因为我的 vue-router 是 hash 模式。
解决方案:把我的 hash 模式换成 history 模式。记得后台也需要配置 nginx 。
第七步:IOS 扫码无反应
当 IOS 能调起接口的那一刻,我以为要成功了,哪知道它就是要与 安卓 与众不同,扫码之后没有任何反应,但是如果你快速地连续多扫几次就会出现结果。
你就说要命不?网上查找了半天,看见有的人说有延时,最后想干脆加个延时算了。
果然加了延时之后就好了。
第八步:扫码结果处理
可能存在问题:
1、iOS设备扫码正常,Android设备扫码后没反应
2、Android设备扫码正常,iOS设备扫码后没反应
原因 :微信开发文档并没有说清楚,其实在微信后台可能是维护了2个接口, 或者是对设备类型进行了区别,总之在 回调 函数中返回的结果封装对象并不是同一个, 所以这要求我们也进行相应的处理, 不然就会出现上面这种默认奇妙的问题。
IOS 返回结果:
Android 结果:
第九步:修改路由
本以为 苹果安卓手机都能够正常扫码,没问题了。但是领导换需求了,之前是扫码放到外边,可以匿名扫。现在要修改成登录之后才可以扫码。
我就把路由修改了一下,先在登录页登录成功之后,再进入扫码页,后台也同步修改了 url 地址,修改完测试发现:
安卓的一切正常。
苹果手机坏了!
奔溃了,看看错误提示:noPermissionJsApi:[],errMsg:"config:ok"。
确定之后有一个错误提示。
errMsg:scanQRCode:the perssion value is offline verifying
一顿网络猛如虎,半天原地打转转!
有前边一次经验教训,我就又去找地址的原因。最后发现是竟然 $router.push 的跳转影响了我的 url ,在 IOS 上的 push 跳转不能写入浏览器的地址栏,但是安卓可以,导致安卓和 ios 跳转之后的地址不同,所以 ios 失败了。
解决办法:
此时就正常运行了。这下满足项目要求了,不会再出什么幺蛾子了!
微信官方开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4
❸ Flash和JS实现的图片幻灯片切换特效
把用到这个效果的文件放在网站的文件夹里,然后imgUrl1="images\f1.jpg"就可以了,原来不显示应该是路径不对
❹ 想要系统学习java到底要学习哪些知识
一、java基础
学习任何一门编程语言,首先要学习的是基础语法,开启Java学习的第一步,当然就是深入掌握计算机基础、编程基础语法,面向对象,集合、IO流、线程、并发、异常及网络编程,这些我们称之为JavaSE基础。当你掌握了这些内容之后,你就可以做出诸如:电脑上安装的迅雷下载软件、QQ聊天客户端、考勤管理系统等桌面端软件。
java学习路线大陆传送门
❺ 手机浏览web网页的时候,自动跳转到对应的wap网页,求代码
|使用以下JS函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
function uaredirect(f) {
try {
if (document.getElementById("bdmark") != null) {
return
}
var b = false;
if (arguments[1]) {
var e = window.location.host;
var a = window.location.href;
if (isSubdomain(arguments[1], e) == 1) {
f = f + "/#m/" + a;
b = true
} else {
if (isSubdomain(arguments[1], e) == 2) {
f = f + "/#m/" + a;
b = true
} else {
f = a;
b = false
}
}
} else {
b = true
}
if (b) {
var c = window.location.hash;
if (!c.match("fromapp")) {
if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|SymbianOS)/i))) {
location.replace(f)
}
}
}
} catch(d) {}
}
function isSubdomain(c, d) {
this.getdomain = function(f) {
var e = f.indexOf("://");
if (e > 0) {
var h = f.substr(e + 3)
} else {
var h = f
}
var g = /^www\./;
if (g.test(h)) {
h = h.substr(4)
}
return h
};
if (c == d) {
return 1
} else {
var c = this.getdomain(c);
var b = this.getdomain(d);
if (c == b) {
return 1
} else {
c = c.replace(".", "\\.");
var a = new RegExp("\\." + c + "$");
if (b.match(a)) {
return 2
} else {
return 0
}
}
}
};
调用方式:
<SCRIPT type=text/javascript>uaredirect("手机站","WEB站");</SCRIPT>
另外,现在分别为PC和WAP开发两个网站的做法已经不再提倡了
推荐使用响应式框架如Bootstrap等,做一个网站,同时兼容PC端和<a href="https://www..com/s?wd=%E7%A7%BB%E5%8A%A8%E7%AB%AF&tn=44039180_cpr&fenlei=-bIi4WUvYETgN-" target="_blank" class="-highlight">移动端</a>
成本更低