AJAX 封装

什么是AJAX?

AJAX是Asynchronous javascript and xml 的缩写,用javascript以异步的形式操作xml(现在操作的是json).

  • 随着谷歌地图的横空,这种不需要刷新页面就可以与服务器通讯的的方式,很快被人们所知。

  • 在传统的web模型当中,客户端向服务器发送一个请求,服务器就会返回整个页面

  • 我们前面学习的form表单来传输数据的方式就属于传统的web模型,当我们点击submit按钮之后,整个页面就会被刷新一下。

  • form表单有三个很重要的属性,分别是methodactionenctype

  • method,一般是get或者post;

  • action是我们要把数据传送到的地址;

  • enctype则是是否对数据进行编码

  • enctype的默认值是 “application/x-www-from-urlencoded”,即在发送前编码所有字符,这个属性值即使我们不写也是默认这个的。

  • 但是当我们在使用包含文件上传控件的表单的时候,这个值就必须更改成“multipart/from-data”,即不对字符进行编码。

  • 而在AJAX模型中,数据在客户端和服务器之间独立传输,服务器不在返回整个页面

AJAX优点

  • 1、页面没有刷新,在页面内容内和服务器通信,给用户的体验好
  • 2、通过异步的形式与服务器通信,不需要打断用户操作,给用户的体验更好
  • 3、减轻服务器负担
  • 4、不需要插件和小程序

AJAX缺点

1.不支持浏览器的后退。
2.安全问题,xss跨站点脚本攻击、sql注入攻击。
3.对搜索引擎支持较差seo。
4. 不支持移动端设备。
5. 违背url 和资源定位的初衷。
复制代码

常见的Web攻击方式:SQL注入、XSS跨站脚本攻击、CSRF跨站点请求伪造

1、sql注入

原理

sql 注入就是通过sql命令插入到web 表单提交输入域名页面请求的查询字符串, 最终达到欺骗服务器执行恶意的sql命令。
登陆操作sql:

  • select * from student where username=‘输入的用户名’ and password=‘输入的密码’

  • 输入的用户名–> ‘ or ‘1’ = ‘1’ or ‘1’ = ‘1

  • 输入的密码–> 1 ‘ or ‘1 ‘=’ 1

  • select * from student where username=” or ‘1’ = ‘1’ or ‘1’ = ‘1’ and password= “

  • select * from student where username=” and password=’1′ or ‘1’=’1′

以上两个SQL语句的where条件永远是成立的,所以验证永远是有效的.

输入的用户名 –> tom’ ; drop table student- –

  • select * from student where username=’tom’ ; drop table student–‘ and password=”
  • 直接把student表给删除了(双连接符表示注释);

防御

1、不相信用户的输入,对用户的输入校验、可以通过正则表达式(必须数字,特定字符串,电话,email的正则),或限制长度;对单引号和双“-”进行转换等

2、永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询``存取。哪怕参数是常量,也请用预编译语句PreparedStatement同时用占位符,如: “select * from table where comment like ?”。

注意:如果参数不是使用的占位符,即使用PreparedStatement执行时也并不是预编译。

3、永远不要使用管理员权限的数据库连接

每个应用使用单独的有权限的数据库连接,这样能降低数据库密码被泄漏而带来的破坏。

4、不要把机密信息直接存放

加密或者hash掉密码敏感的信息;如数据库连接密码用户密码设备密码需要加密存储

2 XSS跨站脚本攻击

2.1 原理

XSS(Cross Site Scripting)跨站脚本攻击

  • 指攻击者在网页中嵌入客户端脚本(例如JavaScript)
  • 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的,比如获取用户的Cookie,导航到恶意网站,携带木马等。

1、Dom-Based XSS 漏洞

基于DOM的XSS,也就是web server不参与,仅仅涉及到浏览器的XSS.
攻击过程如下:小A发现了test.com中的Search.jsp页面有XSS漏洞,Search.jsp的代码如下:

<html>
    <title></title> 
	<body> 
    	Results  for  <%=request.getParameter("term")%>...  
	</body>  
</html> 
复制代码

a准备:
1、偷取信息网址badboy.com
2、恶意url: test.com/search.asp?…

方式: (邮件,QQ) 等方式给到 用户b.
小B点击了这个URL,嵌入在URL中的恶意Javascript代码就会在小B的浏览器中执行,那么小B在test.com网站cookie,就会被发送到badboy网站中,这样小B在test.com的信息就被小A盗了

2、Stored XSS(存储式XSS漏洞)

如一个应用程序从数据库中查询数据,在页面中显示出来,攻击者这个页面输入恶意的脚本数据后,用户浏览此类页面时就可能受到攻击,使得所有访问该页面的用户都面临信息泄露的可能.

小C发现了网站A上有一个XSS 漏洞,该漏洞允许将攻击代码保存在数据库中,于是小C发布了一篇文章,文章中嵌入了恶意JavaScript代码。其他人如小D访问这片文章的时候,嵌入在文章中的恶意Javascript代码就会在小D的浏览器中执行,其会话cookie或者其他信息将被小C盗走。

Dom-Based XSS漏洞威胁用户个体,而存储式XSS漏洞所威胁的对象将是大量的用户。

防御措施

1、在cookie中不要存放一些敏感信息, 或将重要的cookie标记为http only

2、输入过滤校验,对用户提交的数据进行有效性验证,仅接受指定长度范围内并符合我们期望格式的的内容提交。
过滤一些些常见的敏感字符,例如:< > ‘ “ & # \;过滤或移除特殊的Html标签, 例如: <script>, <iframe> , < for <, > for >, &quot for;过滤JavaScript 事件的标签,例如 “οnclick=”, “onfocus” 等等。这里的数据校验除了前台要做,后台也要做。

3、DOM型的XSS攻击防御
  把变量输出到页面时要做好相关的编码转义工作.
要输出到 <script>中,可以进行JS编码;要输出到HTML内容或属性,则进行HTML编码处理。根据不同的语境采用不同的编码处理方式。

3 CSRF跨站点请求伪造

CSRF( Cross-site request forgery )尽管听起来很像XSS跨站脚本攻击,CSRF则是通过伪装用户的请求来访问一个用户已经认证的站点,从而在并未授权的情况下执行特定的操作。与XSS相比,CSRF攻击不大流行和难以防范,所以比XSS更具危险性。

image.png

防范

1.目前主流的做法是使用CSRF Token抵御CSRF攻击,在每个HTTP请求中添加一个随机生成的Token值,一般名为_csrf并且是hidden的,然后由服务端验证,验证通过才是有效的请求。

注意:_csrf的token值一般放在请求参数或请求头里,不能放在cookie中,因为cookie包含在浏览器中可以被获取到。还有我们一般在更新操作才携带这个CSRF Token,这样不会影响外部访问我们网站的查询操作,也不容易导致这个token泄漏,注意要求CSRF Token的更新操作要设计成幂等的。

2.还有一种新兴的方法是使用cookie的SameSite属性,即set-cookie指定属性,当一个来自外部的请求时不能携带cookie。如

Set-Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly; SameSite=Lax
1
SameSite的值有两个:
Strict – 来自同一站点的所有请求都必须携带cookie,其他任何外部的请求都不能携带cookie。
Lax – 当来自同一站点或者顶级导航的请求,且该请求是幂等时携带cookie,否则其他任何请求不能携带cookie。

这样我们在安全的银行网站浏览发出请求时可以携带JSESSIONID的cookie,而来自外部恶意网站的请求就不能携带此
cookie,服务器自然验证后会拒绝该请求。

但是这样也可能给用户带来一些困扰,如从一个邮箱链接里跳转到一个社交网站时,不能携带cookie会要求你再次登陆,给用户带来不便。而且一些较老的浏览器可能不支持SameSite属性。因此不建议使用SameSite作为防范CSRF的唯一方式。

一般如果服务提供的请求是给非浏览器端使用的,不建议开启CSRF防御。

回到ajax

先认识一下AJAX最重要的两个对象:
new XMLHttpRequest()
new ActiveXObject(‘Microsoft.XMLHTTP’)
我们通过AJAX获取数据就是通过这两个对象,一般的主流浏览器支持第一个方法,IE6以下用第二个方法。

对象上三个很重要的方法:
.open(‘method’, ‘url’, ‘true’) 建立对服务器的调用,method参数可以是get、post或者put。url参数可以是相对url或者绝对url,第三个参数是选择异步还是同步,异步是true。这个方法还包括三个可选参数。
5.send(content) 向服务器发送请‘求
6.setRequestHeader(‘label’, ‘value’) 把指定首部设置为提供的值,在设置任何首部之前必须调用open方法。


对象的属性
1.onreadystatechange 状态改变触发器

2.readyState 对象的状态、
    0代表未初始化,此时已经创建了一个XMLHttpRequest对象
    1代表读取中,此时代码已经调用XMLHttpRequest的open方法并且XMLHttpRequest已经将请求发送到服务期。
    2代表已读取,此时已经通过open方法把一个请求发送到服务端,但是还没有收到。
    3代表交互中,此时已经收到http响应头部信息,但是消息主体部分还没有完全接受
    4代表完成,此时响应已经被完全接受。
3.responseText 服务器进程返回数据的文本版本
4.responseXML 服务器进程返回数据的兼容DOM的XML文旦对象
5.status 服务器返回的状态码

这里大致介绍一下状态码。
    状态码的功能
        状态码是用来描述返回的请求结果。借助状态码,我们可以知道是正确的处理了请求还是出现了错误。
        状态码的响应类别一共有5中,比如200,数字中的第一位代表响应的类别,后两位无分类。

状态码的五种类别
    1xx(信息性状态码),接受的请求正在处理
    2xx(成功状态码),请求正确处理完毕
    3xx(重定向状态码),需要进行附加操作以完成请求
    4xx(客户端错误状态码),服务器无法请求类别
    5xx(服务器错误状态码),服务器处理请求出错
其中一般会遇到的大致有以下14种:
    2xx 成功
    200 OK 请求已经被服务器正常处理。
    204 No Content 请求处理成功,但是没有资源可以返回。
    206 Partial Content 表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。 content-Range在首部里面。
    3xx 重定向
    301 Moved Permanently 永久性重定向
    302 Found 临时性重定向,禁止post变成get
    303 See Other 请求的对应资源存在着另一个URI,因使用GET方法定性获取请求的资源
    304 Not Modified 资源已找到,但是为符合要求
    307 Temporary Redirect 临时重定向,与302含义相同。
    4xx 客户端错误
    400 Bad Request 请求报文中存在语法错误
    401 Unauthorized 发送的请求需要有通过HTTP认证的认证信息。如果之前请求过一次,则表示用户认证失败。
    403 Forbidden 不允许访问该资源
    404 Not Found 服务器上没有改资源
    5xx 服务器错误
    500 Internal Server Error 服务器端在执行请求时发生错误
    503 Service Unavailable 服务器暂时处于超负载或正在停机维护,无法处理请求
    注意:不少返回的状态码响应是错误的,但是用户可能察觉不到这点。

1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求


封装ajax
function AJAX(json) {
    var url = json.url,
        method = json.method,
        flag = json.flag,
        data = json.data,
        callBack = json.callBack,
        xhr = null;
    if(window.XMLHttpRequest) {
        xhr = new window.XMLHttpRequest();
    }else {
        xhr = new ActiveXObject('Mircosoft.XMLHTTP');
    }            
    if(method == 'get') {
                url += '?' + data + new Date().getTime(); 
        xhr.open('get', url, flag);
    }else {
        xhr.open('post', url, flag);
    }
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            // 数据已经可用了
            callBack(xhr.responseText);
        }
    }
    if(method == 'get') {
        xhr.send();
    }else {
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urle');
        xhr.send(data);
    }    
}

// 对比jquery 的ajax
$.ajax({
    url:'/comm/test1.php',
    type:'POST',//get
    async: true,//或false ,是否异步,
    data:{
        name:'yang',
        age:25
    },
    timeout:5000,//超时时间
    dataType:'json', //返回的数据格式:json/xml/html/script/jsonp/text
    beforeSend:function(xhr) {
        console.log(xhr);
        console.log('发送前');
    },
    success:function(data,textStatus,jqXHR){
        console.log(data);
        console.log(textStatus);
        console.log(jqXHR);
    },
    error: function(xhr,textStatus) {
        console.log('错误');
        console.log(xhr);
        console.log(textStatus);
    },
    complete: function() {
        console.log('结束');
    }
})
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享