HTTP和应用问题
HTTP协议
应用层协议,针对服务器端和客户端的应用之间的传输协议
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议
RFC2616,HTTP协议采用了请求/响应模型
版本
HTTP/1.0
这是第一个在通讯中指定版本号的HTTP 协议版本,至今仍被广泛采用,特别是在代理服务器中【一般用于邮箱代理服务器】
Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 服务器。内存少,并发能力强
HTTP/1.1
当前版本。默认采用keep-alive模式,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
HTTP/2
报文
Request请求
消息头部:
- Accept 可接受的数据类型,MIME;
- Accept-Language
- Accept-Encoding
- User-Agent 发送端的系统信息【以Mozilla标准:浏览器类型,OS类型,使用的平台库等】
- Referer 当请求的uri不存在时,转至的上一个界面
- Host 请求端的域名
- Connection 连接方式,持久连接 keep-alive
-
Cookie
get方式最多传递2038个字符;post将参数信息保存在request报文的请求体中
=》通过GET方法提交数据,则数据存放在QUERY_STRING环境变量中,而POST方法提交的数据则可以从标准输入流中获取。
Response返回
状态行
协议版本号 状态码 状态code
消息报头
Location 重定向接受到的Referer所指向的位置
Server 服务器端的信息
....
消息体
消息头部:
- Content-Encoding
- Content-Language
- Content-Length 字节方式存储
- Content-Type
-
date Last-Modified、Expires实体报头域给出响应过期的日期和时间
HTTP状态码:
1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
3xx:重定向--要完成请求必须进行更进一步的操作。
4xx:客户端错误--请求有语法错误或请求无法实现。
5xx:服务器端错误--服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下:
200 OK:客户端请求成功。
300:Multiple Choices/多重选择,表示被请求的文档可以在多个地方找到
301:Moved Permanently,指所请求的文档在别的地方,浏览器会自动连接到新的URL
302:Found/找到,临时交换地址而不是永久
303:See Other/参见其他信息
304:未修改;
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
tcp三次握手四次挥手协议
client首先发送连接请求,发送报文段,包括ack=0,syn=1,seq=x
server收到请求,为该TCP分配缓存及变量,发送报文段,包括ack=1,syn=1,ack=x+1,seq=y
client收到后确认,为该tcp分配缓存及变量,包括ack=1,syn=1,ack=y+1,seq=x+1
client发final报文,
server仍在传输,发ack报文;
待完成传输后,发final报文
client收到后发ack报文,server收到后才可以断开连接
相应状态:listen sys-send syn-revd established fin-wait close-wait time-wait last-ack close
=》socket连接建立
UDP和TCP的区别:
TCP,传输控制协议;面向连接的、可靠的字节流传输服务。bs交换数据前需三次握手协议建立连接;通过包的序号保证超时重发、重复包丢弃、顺序传输;bs双方需建立tcp缓存及变量空间,系统开销大些。
UDP,用户数据报协议;面向无连接的、非可靠的数据报协议。数据结构简单、系统开销小,传输速度快。=》可以在应用层增加相关机制保证可靠与控制机制。
FTP、Telnet、SMTP(邮件传输协议,25)、HTTP、POP3(支持使用客户端远程管理在服务器上的电子邮件,提供了SSL加密的POP3协议被称为POP3S)等;
UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP(简单网络管理协议)、QQ、流媒体协议等
现代浏览器:
从输入URL到页面下载完的过程中都发生了什么事情:
1、DNS的domain递归解析【首先浏览器缓存、在再OS缓存中找,没有向localDNS服务器找,向根服务器找;根服务器返回区域的DNS服务器】
根据域名级别,一次从一级域名向二级、三级找。
2、tcp的三次握手【根据ip发起网络连接,可能遇到重定向问题,那重复1找到重定向之后的server】
3、browser的httprequest【包括资源路径、身份验证】
4、server的httpresponse【client收到响应内容,页面中的url,如图像等资源再次请求;再进行网页渲染,包含css之后的html及图片】
3、4主要和带宽有关
解析html构建dom树->构建render树->布局render树->绘制render树。
加载速度的优化:
浏览器内核技术:缓存、预取、压缩、并行;
DNS级缓存预取:1、浏览器DNS缓存;2、系统DNS缓存;3、Hosts文件;4、各个DNS服务器上的缓存
HTTP和HTTPS的区别:
https安全性比http高,基于http+ssl,端口号为443。主要是可进行加密传输、身份认证
1、身份认证,需要server端有CA证书,证明服务器用途类型;
2、bs之间所有传输内容都经过加密; i. 具体讲,是客户端产生一个对称的密钥,通过server 的证书来交换密钥. 一般意义上的握手过程. ii. 接下来所有的信息往来就都是加密的. 第三方即使截获,也没有任何意义.
【SSL,SSL运行在TCP/IP层之上、应用层之下,为应用程序提供加密数据通道,它采用了RC4、MD5 以及RSA等加密算法,使用40 位的密钥,适用于商业信息的加密。HTTPS和SSL支持使用X.509数字认证】
由于https 要还密钥和确认加密算法的需要.单握手就需要6/7 个往返;接下来才是具体的http协议,每一次响应或者请求, 都要求客户端和服务端对会话的内容做加密/解密。=》所以对带宽及cpu都有压力
前端安全性问题:
XSS,跨站脚本攻击(Cross Site Script) 。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行。如:弹出广告
CSRF,跨站点伪造请求(Cross Site Request Forgery)。顾名思义就是 通过伪造连接请求在用户不知情的情况下,让用户以自己的身份来完成攻击者需要达到的一些目的。如:钓鱼网站
cookie劫持,通过获取页面的权限,在页面中写一个简单的到恶意站点的请求,并携带用户的cookie。 获取cookie后通过cookie 就可以直以被盗用户的身份登录站点。这就是cookie 劫持。
nodejs:WWW-Authenticate报头域
项目升级为https:
由于https的网站内嵌其它项目时,要求该项目也是https认证的;
需要公网CA证书
ajax
Asynchronous JavaScript and XML,在服务器和客户端之间充当了一个缓冲器
原理
- 通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而局部更新页面
- 本身继承了XMLHttpRequest 对象,所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject),用于在后台与服务器交换数据
- 由下列技术组合而成:
- 使用CSS和XHTML来表示;
- 使用DOM模型来交互和动态显示;
- 使用XMLHttpRequest来和服务器进行异步通信;
- 使用javascript来绑定和调用
$.ajax({
type:'GET', //默认get
dataType:'json', //预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断
contentType:'application/x-www-form-urlencoded', //发送信息至服务器时内容编码类型
url:encodeURI(''), //特殊字符需要编码
timeout:10000, //设置请求超时时间(毫秒)。此设置将覆盖全局设置
data:{}, //post时传递数据
async: true, //默认异步
cache: true,//默认值: true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面
sucess:function(data,textStatus){
},
error:function(XMLHttpRequset,textStatus,error){
}
});
-
好处:
- 页面无刷新,异步方式不用打断用户的操作;
- 将一些服务器的工作转嫁到客户端;
- 基于标准化的并被广泛支持的技术,不需要小插件等
-
缺点:
- ajax干掉了back按钮,即对浏览器后退机制的破坏【google通过创建或使用一个隐藏的IFRAME来重现页面上的变更】;
- ajax的逻辑处理对客户端的安全扫描隐藏
Ajax不能重定向的问题
-
问题:发送一个接口请求,接口本身重定向到login界面;browser本身发送两次请求,一个是接口的请求,response中是302状态,一个是重定向的请求,状态是200,但不跳转到login
302 Found 是HTTP协议中的一个状态码(Status Code),可以简单的理解为该资源原本确实存在,但已经被临时改变了位置
原因:默认ajax是不支持重定向,因为ajax本身就是局部刷新,不重新加载页面。导致虽然客户端接受到了重定向,并发出了请求,状态码也是200,但是浏览器并没有跳转
解决:
前端根据json数据自己跳转login
java的重定向:
- 当使用转发forward时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程;直接经由server完成不同url访问
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
try {
rd.forward(request, response);
return; //如果不加,会报Cannot forward after response has been committed
}catch(Exception e){
}
- 重定向方式的含义是第一个页面通知浏览器发送一个新的页面请求
httpServletResponse.sendRedirect(url);
- sendRedirect转发更快,而且能保持request内的对象=》可以解决页面session传递问题;两者在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中清除
跨域
同源策略的限制。一般为了安全型,要求在域域名、端口号、协议上是一致的
不会判断是否是同一个ip
但限制了注入iframe和ajax的应用,需要跨域访问
- js跨域访问方式:
使用document.domian来跨域
jsonp
JSON with Padding,动态创建script;同源策略不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)
- 示例:
function jsonpCallback(result) {
//alert(result);
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
}
var JSONP=document.createElement("script");
JSONP.type="text/javascript";
JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback"; //客户端注册一个jsonp,将callback名字传递给服务器
document.getElementsByTagName("head")[0].appendChild(JSONP); //将该源像web中元素引入
//服务器端以js语法创建callback函数
- 缺点:1、需要前后端协作;2、url使用相对路径;3、jsonp是get形式,承载的信息量有限
使用window.name进行跨域数据传输
CORS
Cross-origin resource sharing 定义一种跨域访问的机制,可以让AJAX实现跨域访问
实现此功能非常简单,只需由服务器发送一个响应标头即可;但需要特定浏览器支持
支持的浏览器:
后台设置:
1、
((HttpServletResponse) response).setHeader("Access-Control-Allow-Origin","*"); //cy:调试阶段,后期去掉
((HttpServletResponse) response).setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); //解决application/x-www-form-urlencoded, multipart/form-data, or text/plain跨域问题
//或者指定域名
response.setHeader("Access-Control-Allow-Origin","name");
2、Spring MVC 4.2.5以后新增的支持跨域的注解@CrossOrigin
- 限制:
- 只能使用ajax请求,而不是form中action
-
Access-Control-Allow-Origin: *
允许任何来自任意域的跨域请求,那么久存在被 DDoS攻击的可能
超时重试
如果应用不设置超时,则可能会导致请求响应慢,慢请求累积导致连锁反应;
重试次数太多会导致多倍请求流量,即模拟了DDoS攻击;读服务天然适合重试,但写服务大多不能重试
在进行代码Review时,一定记得Review超时与重试机制
可能出现的超时节点:
- 代理层超时与重试:如Haproxy、Nginx、Twemproxy,这些组件实现代理功能,如Haproxy和Nginx可以实现请求的负载均衡
- Web容器超时:如Tomcat、Jetty等,提供HTTP服务运行环境的
- 中间件客户端超时与重试:如JSF(京东SOA框架)、Dubbo、JMQ(京东消息中间件)
- 数据库客户端超时:如Mysql、Oracle,需要分别设置JDBC Connection、Statement的网络连接/读/写超时时间。事务超时时间,获取连接池连接等待时间
- 前端Ajax超时:浏览器通过Ajax访问时的网络连接/读/写超时时间
问题:
新平台(端口彼此独立,不共享session),后端接收到两次请求,第1次是有session情况,第2次是访问另外的端口跳转到login界面(确定是filter中转的)解决:
- 反向代理Nginx的配置
增加配置:
proxy_next_upstream http_502 http_504 error timeout invalid_header; #表示对error和timeout的进行重试到下一个节点
proxy_read_timeout 60s; #连接成功后,后端服务器响应时间(代理接收超时时间)
proxy_send_timeout 60; #后端服务器数据回传时间(代理发送超时时间)
proxy_connect_timeout:75; #nginx连接后端的超时时间,一般不超过75s
- weblogic超时设置
一、web.xml
设置WEB应用程序描述符web.xml里的<session-timeout>元素。这个值以分钟为单位,并覆盖weblogic.xml中的TimeoutSecs属性,此例表示Session将在54分钟后过期。
<session-config>
<session-timeout>54</session-timeout>
</session-config>
当<session-timeout>设置为-2,表示将使用在weblogic.xml中设置的TimeoutSecs这个属性值。
当<session-timeout>设置为-1,表示Session将永不过期,而忽略在weblogic.xml中设置的TimeoutSecs属性值。该属性值可以通过console控制台来设置
二、weblogic.xml
设置WebLogic特有部署描述符weblogic.xml的<session-descriptor>元素的TimeoutSecs属性。这个值以秒为单位。该文件放在项目的web-inf下。
<session-descriptor>
<session-param>
<param-name>TimeoutSecs</param-name>
<param-value>3600</param-value>
</session-param>
</session-descriptor>
默认值是3600秒
客户端超时设置
Connection: keep-alive
每次http请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重用连接;Keep-Alive: timeout=time
,即告知客户端长连接超时时间
http/1.0默认是关闭长连接的,需要添加HTTP请求头“Connection:Keep-Alive”才能启用。而http/1.1默认启用长连接,需要添加HTTP请求头“Connection: close”才关闭ajax超时设置
Ajax 请求是限时的,所以错误警告被捕获并处理后,可以用来提升用户体验。请求超时这个参数通常就保留其默认值,要不就通过 jQuery.ajaxSetup 来全局设定,很少为特定的请求重新设置 timeout 选项