美文网首页
浅谈Web应用开发

浅谈Web应用开发

作者: Java架构师CAT | 来源:发表于2019-12-03 11:07 被阅读0次

    随着浏览器能力的增强,绝大部分工作任务都是基于浏览器的应用开发。从2008年底,我第一次接触Web应用开发至今,已接触过Web Form、MVC、前后端分离等不同的开发模式,近期也在从事基于vue.js+Spring Cloud的Web应用开发。在Web应用开发方面积累了一些经验,在此与大家分享。由于一直都是“做中学”,以下描述可能不够专业、不够系统,所述如有不妥之处,欢迎拍砖指正。

     什么是Web应用 

    “Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。(引自百度词条)更通俗地说,就是我们日常所访问的网站。

    传统上,Web应用将静态资源和动态数据请求打在一个包中,如以jsp开发的Web应用中,jsp页面和后台数据处理逻辑通常打在一个war包中。当前,Web应用的开发通常采用前后端分离的开发模式,即前端开发人员开发html/css/js等静态资源,后端开发人员提供数据服务接口(如rest api)。在这种模式下,浏览器加载静态资源后,通过发起数据请求访问服务端提供的数据服务,其好处在于,让开发人员专注于自己擅长的工作。

    作为Web应用开发人员应该对图中所示非常熟悉。接下来,根据与日常讨论中,部分同事遇到的问题做一些简单总结。

    浏览器是如何工作的

    从用户输入域名到看到页面,浏览器主要做了以下几件事:

    1.DNS解析

    用户输入URL后,浏览器“询问”DNS服务器此域名对应的IP地址,这里不展开讨论DNS服务器如何将域名转换为IP地址。

    2.发起HTTP请求

    确定此域名对应的IP后,浏览器根据IP地址和端口与目标服务器进行建立TCP连接。根据URL中的协议、Path等,通过已建立的TCP连接发起HTTP请求,并等待服务端的响应。

    3.渲染

    浏览器将服务端响应解析成用户能够理解的页面:

    浏览器可以解析html,加载标记中包含的额外资源(如js文件或css文件等),并将它们呈现给用户;

    浏览器加载的js也可以发起ajax请求,js根据响应的数据动态修改html的内容。

    (更多关于浏览器的渲染原理的内容,参见《浏览器的工作原理:新式网络浏览器幕后揭秘》https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/

     关于浏览器的其他事项 

    1.HTTP协议

    浏览器通常以HTTP协议与服务端进行数据交互。HTTP协议是单向的请求-响应协议,浏览器封装HTTP请求发送给服务器,服务器接收到请求后,将响应数据封装成HTTP响应返回给浏览器,若没有请求就没有响应。

    同时,HTTP协议也是无状态的协议,即在协议层面,无法辨别两个请求的关联关系,如协议本身没有机制将登录请求后续的数据请求绑定。在实践中,通常有两个方式来保持这种“状态”:

    (1)客户端方式

    将状态信息存储于浏览器,服务端不存储状态信息,每次的HTTP请求都带上此状态信息,最常用的携带方式是置于cookie中,因为浏览器每次发起HTTP请求都会自动带上“可携带”的cookie。

    例如,现在业界常用的JWT(JSON Web Token)方案,在验证用户的密码后,服务端将生成一个JSON对象并将其发送回用户,浏览器在发起后续的请求中发回JSON对象,服务端通过此JSON对象的内容将多个请求关联到同一个用户上。为了防止用户篡改数据,服务端将对JSON对象进行签名,甚至加密。

    需要注意的是,由于apache等服务端对header的长度有限制,JWT对象的内容不宜过长,否则apache等服务端将响应状态码为400的报文。

    (2)服务端方式

    将状态信息存储于服务端session,只将sessionID返回给浏览器,每次的HTTP请求都带上此sessionID。例如在cookie中带上sessionID,服务端从cookie中取出sessionID并以此在存储中查找对应的状态信息。这种方式的问题在于,对于分布式架构,需要共享存储(如将状态信息存储于redis中)的支持。

    2.Websocket

    随着Web应用的功能日益丰富,只能先有请求才有响应的HTTP协议已无法满足用户需求,于是Websocket协议便应运而生。Websocket协议是双向的数据通信协议,支持服务端主动向浏览器推送消息,大部分现代浏览器都已支持Websocket协议。在需要消息推送的场景(如web聊天室),可以尝试Websocket协议的方式实现。

    3.同源策略

    所谓同源是指域名,协议,端口相同

    同源策略是浏览器最核心最基本的安全机制,即在没有明确授权的情况下,限制非同源的document读取或设置当前document的某些属性。

    例如,在没有明确授权的情况下

    页面可以向任何服务端发起请求,但是收到服务端响应后,将检查响应是否与自己同源,如果收到非同源的数据将报错;

    请求中只携带同源的cookie;

    JS脚本只允许读取或设置同源的cookie、SessionStorage、LocalStorage和IndexDB等数据。

    在实践中,有多种方式绕过同源策略的限制,但是,作为浏览器最基本的安全机制不建议在浏览器端轻易放开此限制。

    前后端分离的服务端实现

    自2008年底接触Web应用开发至今,我先后接触了WebForm、MVC、前后端分离等不同的开发模式。在最近的实践中,我们采用了前后端分离的开发模式,这也是当前最流行的开发模式,因此这里仅介绍前后端分离的服务端实现。

    如图所示,是我们通常采用的模块划分方案,包括反向代理、静态资源和Java后端服务。其中,反向代理用于解决浏览器同源策略的限制,在服务端对静态资源和数据服务请求进行分离,这样对于浏览器来说,静态资源和数据服务的请求就在同域下。

    1.Web前端开发

    目前,前端开发流行三大框架:VueJs、AngularJs和ReactJs。对比三个框架,VueJs上手简单、社区活跃、中文文档丰富,作为快餐主义者,自然而然地选择了VueJs。具体的vueJs开发学习内容,建议直接参考官方文档https://cn.vuejs.org/v2/guide/,这里不再赘述。前端开发完成的静态资源经打包压缩后,托管于Web服务器,通常的Web服务器有Apache、Nginx,前端页面通过事先定义的数据服务接口与后端服务交换数据。

    2.Java后端开发

    与前几年流行的SSH框架不同,当前Java后端开发中,基于Spring Cloud的应用开发占据了大半江山。Spring Cloud作为第二代微服务的代表性框架,是一个基于Spring Boot实现的、用于快速构建分布式架构的应用的工具集,其中涉及配置管理、服务发现、熔断器、路由转发等诸多工具。我的第一本Spring Boot入门书籍是《JavaEE开发的颠覆者: Spring Boot实战》,个人认为是一本不错的入门书籍。

    在图中所示的架构中,各模块的功能概述如下:

    认证与权限管理服务负责与个性化的认证系统(UASS)、权限管理系统(机构员工)对接,避免了各子服务重复对接的工作。

    网关与认证、权限系统进行对接,负责访问控制、路由转发、负载均衡和流量控制,承担了传统应用的SessionFilter的作用。

    业务应用收到网关转发的请求,即已通过了访问控制,只需基于网关提供的用户信息专注于业务逻辑的实现。

    这种架构的优势在于,在产品输出过程中,面对不同的认证与权限管理体系,只需在认证与权限管理服务做相应适配,业务应用的实现逻辑可基本保持不变,大大提高了系统的适应性、可扩展性。当然,此架构中仍缺少配置中心、监控中心等服务模块,也缺少服务间安全调用方案(安全性仍依赖于网络隔离),对于这些模块,我们也还在积极探索中。

     Nginx的使用提示 

    实践中,最常用的Web服务器有Apache和Nginx。Nginx以其轻量级、占用资源少、并发能力强、使用方便(配置简单、重启方便),既可以作为反向代理,也可以用作Web服务器,腾讯、淘宝、京东、百度、新浪、网易等大厂都在使用Nginx。在公有云系统的部署中,我们也大量使用Nginx(相比之下,Apache的配置实在太麻烦)。

    各种资料中都有Nginx配置的详细介绍http://www.nginx.cn/doc/,这里介绍我们在使用Nginx过程中曾遇到的几个不容发现的问题。

    1.Resolver

    通常,内网和互联网是隔离的,当内网访问互联网服务时可在Nginx配置反向代理,如:

    location/ccb {

    proxy_passhttp://www.ccb.com/;

    }

    此时,内网仍然无法调用互联网服务,需要配置resolver,告诉Nginx应通过哪个DNS服务器解析www.ccb.com的域名。

    2.$http_host

    location/gateway {

    proxy_passhttp://gateway;

    proxy_set_header Host $host;

    }

    当后端gateway需要将用户重定向到同域下的其他页面时,通常重定向参数只设置路径而不提供IP和端口,如果采用上述配置,重定向后将丢失参数。如用户访问http://portal:8080/xxx,gateway收到请求后将用户重定向到/yyy,则用户将被重定向到http://portal/yyy,端口8080将丢失。此时只需要做如下修改即可。

    location/gateway {

    proxy_passhttp://gateway;

    proxy_set_headerHost $http_host;

    }

    3.Proxy_pass

    location/ccb {

    proxy_passhttp://www.ccb.com/; #(1)

    proxy_passhttp://www.ccb.com; #(2)

    }

    在配置中注意上述两种情况的差异,如果请求路径为/ccb/xxx,

    对于(1),转发后的请求为http://www.ccb.com/xxx;

    对于(2),转发后的请求为http://www.ccb.com/ccb/xxx;

    相关文章

      网友评论

          本文标题:浅谈Web应用开发

          本文链接:https://www.haomeiwen.com/subject/jlhcgctx.html