首页 > 网站 > WEB开发 > 正文

Ajax

2024-04-27 14:19:28
字体:
来源:转载
供稿:网友

Ajax

参考 :http://javascript.ruanyifeng.com/bom/ajax.html#toc6

Javascript 高级程序设计第三版. 期待第四版啊!

本篇主要记入一些基本和常使用到的ajax方法

服务端是用 asp.net ashx 来接收的。

js部分不考虑游览器兼容的问题.

简单的理解 , ajax就是发送http请求,而不重启或刷新页面。

这里从发送一个ajax请求还有一个 http 头说起吧

        var xhr = new xmlHttPRequest();         xhr.open("GET", "//localhost:5715/learn/ajax/ajaxhand.ashx", true);         xhr.setRequestHeader("Content-Type", "application/json"); 必须在open之后才能set哦           xhr.setRequestHeader("customHeader", "value");        xhr.send(null);

整个请求都是依靠这个 xmlhttpRequest 实例对象来完成的。

open方法

-参数1是请求的类型method, 比如 GET,POST,PUT,DELETE 等

-参数2是请求的网址

-参数3是表示是否是一个异步请求.

setRequestHeader 方法 (必须在open之后才能set哦)

请求时发送给服务端的头信息 name 和 value

我们可以自定义一些请求头

send 方法

参数1是请求时具体内容(body). 有head 就有 body嘛 , 但是GET请求就不可以有body哦,即使你放了也传不去后台。

参数除了string 还支持 ArrayBuffer ,Blod,FormData类型等 ..之后会讲到

好了我们看看后台如何获取这些信息

<%@ WebHandler Language="C#" Class="ajaxhand" %>using System;using System.Web;using MySQL.Data.MySqlClient;using System.Data;using Newtonsoft.Json;using Newtonsoft.Json.Linq;using System.Collections.Generic;using System.Collections;using System.Web.sessionState;using System.Linq;using System.Reflection;using System.IO;using System.Text;using stooges_funcV3;using System.Collections.Specialized;public class ajaxhand : IHttpHandler {    public void ProcessRequest (HttpContext context)     {        //遍历header        NameValueCollection head = context.Request.Headers;        String[] headersKey = head.AllKeys;        foreach (string key in headersKey)        {            String[] values = head.GetValues(key);            string value = values[0]; //通常只有一个        }                  context.Response.ContentType = "text/plain";        context.Response.Write("Hello World");           }     public bool IsReusable {        get {            return false;        }    }}
View Code

整体大致上是这样,我们通过偏离header就可以完全获取header资料了.

除了header 我们还常会通过urlParams来做传信息,比如

        var urlParams = "?" + encodeURIComponent("k ey") + "=" + encodeURIComponent("v alue"); //?a%20b=b%20c  记得要加密        xhr.open("GET", "//localhost:5715/learn/ajax/ajaxhand.ashx" + urlParams, true);
        string value = context.Request["k ey"];        string value2 = context.Request.QueryString["k ey"];         string[] allkeys = context.Request.QueryString.AllKeys; //遍历        foreach (string key in allkeys)        {                    string paravalue = context.Request.QueryString[key];        }

还有 cookie

        string[] keys = context.Request.Cookies.AllKeys;        foreach (string key in keys)        {            string x = context.Request.Cookies[key].Value.ToString();        }

到此我们先说说响应的部分了

        var xhr = new XMLHttpRequest();        xhr.onreadystatechange = function () {            if (xhr.readyState == 1) {                console.log("open"); //调用了open方法            }            else if (xhr.readyState == 4) { //3表示接收到了响应但是没有完成 , 4则表示响应已完成。                 if (xhr.status >= 200 && xhr.status <= 300 || xhr.status == 304) {                                      console.log(xhr.responseText); //响应的返回值                }                else {                    console.log("ajax fail");                }            }                    }        xhr.open("GET", "//localhost:5715/learn/ajax/ajaxhand.ashx", true);        //xhr.setRequestHeader("Content-Type", "application/json");                  xhr.send(null);

监听 onreadystatechange

readyState 表示 xhr当前的状态 .

1代表open被调用了。

3代表接收到响应了,但还不完整(可以用这个做http流,之后可能会讲到)

4代表已经完成.

xhr.status 就是需要返回代号。 比如404表示找不到地址,这个熟了吧 .

一般200表示很好。 304 表示请求的资料本地缓存还没有过期可以直接使用。

xhr.responseText 就是我们要的数据啦.

        context.Response.ContentType = "text/plain";        context.Response.Write("Hello World");      

服务端的响应大概是这样的。

   var str = xhr.getAllResponseHeaders(); //返回的是string 要自己分析   var value = xhr.getResponseHeader("key"); //直接取值

前端获取响应头信息

上面都是在说GET,现在我们来写一个POST请求看看

xhr.open("POST", "//localhost:5715/learn/ajax/ajaxhand.ashx", true);xhr.send("hello"); //纯字符串

服务端 :

 string method = HttpContext.Current.Request.HttpMethod; //POST StreamReader reader = new StreamReader(context.Request.InputStream, Encoding.UTF8); string value = reader.ReadToEnd();  //hello

表明contentType 是 FormData

        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //表明是form格式        var someData = encodeURIComponent("a b") + "=" + encodeURIComponent("b c"); //?a%20b=b%20c 要key=value 和加密哦        xhr.send(someData);

服务端 :

  string value = context.Request["a b"]; //b c 一样拿的到  string value2 = context.Request.QueryString["a b"]; //null QueryString只能拿到url的params

服务端在获取的时候最好先判断 contentType 来决定用什么方式获取资料,比如json的话还要反序列化等等。

再来我们试试用表单提交

    <form id="formId">        <input type="text" name="name" value="keatkeat" />        <input type="text" name="age" value="10" />         </form>
        //xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //不用声明了        var formElem = document.getElementById("formId");        var formData = new FormData(formElem); //把表单丢进去        formData.append('csrf', 'a b c'); //扩展表单内容        xhr.send(formData);
关键是使用了 new FormData append 方法可以添加而外的key value 给form 会自动加密 可以看出来,这个方式取代了之前的post form 方案,这个不用写header也不用加密等,更方便了。服务端依据 : 
        string [] keys =  context.Request.Form.AllKeys;        foreach (string key in keys)        {            var value = context.Request.Form[key];        }

现在我们来试试上传文件

            xhr.upload.onprogress = function (e) {                if (e.lengthComputable) {                    var percentComplete = e.loaded / e.total; //百分比                                   }            }            xhr.upload.onload = function () {                console.log("done upload");            }

首先是监听上传的进度

       <input id="fileId" type="file" multiple="multiple" />            var formData = new FormData(); //把表单丢进去            var fileElem = document.getElementById("fileId");            var files = fileElem.files;            for (var i = 0; i < files.length; i++) {                var file = files[i];                formData.append("file" + i, file);            }            xhr.send(formData);

一个上传控件 , 这里是支持多文件上传的 .

这里我们循环formData.append(fileName,file); 是因为一个控件只有一个name 但是我们却是 multiple files ,这样在服务端不好区分开来。

服务端很简单 :

        string[] keys = context.Request.Files.AllKeys;        foreach (string key in keys) //key 就是我们循环取的name        {            HttpPostedFile file = context.Request.Files[key];            file.SaveAs(context.Server.MapPath(@"~/image.png")); //直接保存        }

此外我们还可以中断请求

        xhr.onabort = function () {                alert("aboat");            }            xhr.send("str");            setTimeout(function () {                xhr.abort();            }, 1);

通过 abort 方法来中断,也可以监听

再来我们看看 ajax 如何跨域请求.

基本上js是不用去管请求是否是跨域的。游览器会帮我做好。除了IE (低版本8,9)

那么主要是服务端要设置一下。

一个跨域的http 请求会附带一个header key =Origin , value = '地址'

        String[] origin = context.Request.Headers.GetValues("Origin"); //跨域的http请求会带着个header        if (origin != null)         {            string requestFromUrl = origin[0]; //装原来的url             //验证一下决定要不要运行它访问            if (true)            {                context.Response.AddHeader("access-Control-Allow-Origin", requestFromUrl); //把url设定进去就可以了                           }            else            {
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表