zoukankan      html  css  js  c++  java
  • 通过jQuery或ScriptManager以Ajax方式访问服务

    1、客户端和服务端

    服务端对外提供服务时,可以通过handler或者webservice。handler比较轻便,但是难以对外公开,只有程序员自己知道它到底做了些什么工作。webservice可以将服务对外公开,调用也方便,更加专业些。如果不是要公开的接口,handler完全可以胜任了。下面是将webservice发布的效果。

    客户端在调用服务端的服务时,最简单的莫过于使用jQuery了。当然微软也提供了ScriptMananger来访问WebService。他们之间的关系可以用下图说明。

    2、搞一个Handler

     1 using System;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Web;
     6 using System.Web.Script.Serialization;
     7 
     8 namespace WjjStudy.handler
     9 {
    10     /// <summary>
    11     /// info 的摘要说明
    12     /// </summary>
    13     public class info : IHttpHandler
    14     {
    15 
    16         public void ProcessRequest(HttpContext context)
    17         {
    18             //提取参数
    19             //context.Request.QueryString["name"];
    20             //context.Request.Form["name"];
    21             
    22             //json 的 contentType 常见写法有 : text/json & text/javascript .
    23             //但是 这个 text/json 其实是根本不存在的, 而 text/javascript 在有些时候客户端处理起来会有歧义. 
    对于json的contentType , rfc里定义的标准写法是 :application/json.在这里毫无疑问 我们应该选择标准写法的 application/Json。
    24 //如果指定为text/json, 处理方式:firefox,下载;chrome,直接显示。 25 context.Response.ContentType = "application/json";//只有具体指定了,firefox的json插件才起作用! 26 //context.Response.Write("{"name":"wjj","age":"25"}"); 27 Hashtable ht = new Hashtable(); 28 ht["name"] = "wjj"; 29 ht["age"] = "21"; 30 31 JavaScriptSerializer js = new JavaScriptSerializer(); 32 string json = js.Serialize(ht); 33 context.Response.Write(json); 34 } 35 36 public bool IsReusable 37 { 38 get 39 { 40 return false; 41 } 42 } 43 } 44 }

    3、搞一个WebService

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using System.Web.Script.Serialization;
     6 using System.Web.Script.Services;
     7 using System.Web.Services;
     8 using WjjStudy.model;
     9 
    10 namespace WjjStudy.asmx
    11 {
    12     /// <summary>
    13     /// info 的摘要说明
    14     /// </summary>
    15     [WebService(Namespace = "http://gagarin.org/")]
    16     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    17     [System.ComponentModel.ToolboxItem(false)]
    18     // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 
    19     [System.Web.Script.Services.ScriptService]
    20     public class info : System.Web.Services.WebService
    21     {
    22 
    23         [WebMethod(Description = "返回类型是对象")]
    24         public Student GetStudent(int para)
    25         {
    26             return new Student { ID = para, Name = "wjj" };
    27             //{"d":{"__type":"WjjStudy.model.Student","ID":100,"Name":"wjj"}}
    28         }
    29 
    30         [WebMethod(Description = "返回类型是字符串")]
    31         //[ScriptMethod(ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)] 没用
    32         public string GetStudentJson(int para)//返回给客户端为json字符串,需要将该字符串再次序列化。
    33         {
    34             //1、拼凑JSON字符串
    35             //return "{"ID":" + para + ","Name":"wjj"}";
    36 
    37             //2、借助JavaScriptSerializer
    38             //this.Context.Request.ContentType = "application/json";//没用
    39             //this.Context.Response.ContentType = "application/json";//没用
    40 
    41             JavaScriptSerializer jss = new JavaScriptSerializer();
    42             return jss.Serialize(new Student { ID = para, Name = "wjj" });
    43             //{"d":"{"ID":100,"Name":"wjj"}"}
    44         }
    45     }
    46 }

    4、jQuery访问Handler

    jQuery访问Handler,只要调用$.ajax({}),将url传递进去就ok了,比较简单,就不演示了。当然如果你不怕麻烦你可以使用JS原生的XMLHttpRequest来访问它。

     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <title>xmlhttprequest实现ajax访问</title>
     6     <script type="text/javascript">
     7         function createXHR() {
     8             var xhr = null;
     9             try {
    10                 // Firefox, Opera 8.0+, Safari,IE7+
    11                 xhr = new XMLHttpRequest();
    12             }
    13             catch (e) {
    14                 // Internet Explorer 
    15                 try {
    16                     xhr = new ActiveXObject("Msxml2.XMLHTTP");
    17                 }
    18                 catch (e) {
    19                     try {
    20                         xhr = new ActiveXObject("Microsoft.XMLHTTP");
    21                     }
    22                     catch (e) {
    23                         xhr = null;
    24                     }
    25                 }
    26             }
    27             return xhr;
    28         }
    29         //在收到响应后相应数据会填充到XHR对象的属性,有四个相关属性会被填充:
    30         //1. responseText:作为响应主体被返回的文本
    31         //2. responseXML:如果响应内容的类型是”text/xml”或”application/xml”,这个属性将保存包含着相应数据的XML文档
    32         //3. status:响应的HTTP状态(200,404,500等)
    33         //4. statusText:HTTP状态说明
    34         var xhr = createXHR();
    35         //检查XHR对象的readyState属性,该属性表示请求/响应过程中的当前活动阶段,每当readyState值改变的时候都会触发一次onreadystatechange事件。必须在open前就指定该处理函数。
    36         xhr.onreadystatechange = function () {
    37             //readyState 
    38             //0:请求未初始化;
    39             //1:服务器已建立连接;
    40             //2:请求已接受;
    41             //3:请求处理中;
    42             //4:请求已完成,且响应就绪。
    43             if (xhr.readyState == 4 && xhr.status == 200) {
    44                 console.log('Original Ajax: ' + xhr.responseText);
    45             }
    46         }
    47         xhr.open('post', '../handler/info.ashx', true);//get或post,ashx需要发布后才可以访问
    48         xhr.setRequestHeader("userdef", "haha");//open后,send前
    49         xhr.send('{para:100}');
    50     </script>
    51 </head>
    52 <body>
    53 </body>
    54 </html>

    5、使用jQuery和ScriptManager访问WebService及比较

    这里才是本文想说的重点呢。因为有好几个地方需要注意,否则很纠结。以下是本人测试得到的结论,仅供参考。

    测试的代码如下(由于用到了ScriptManager,这是一个aspx文件):

      1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="testAjax.aspx.cs" Inherits="WjjStudy.aspx.testAjax" %>
      2 
      3 <!DOCTYPE html>
      4 
      5 <html xmlns="http://www.w3.org/1999/xhtml">
      6 <head runat="server">
      7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      8     <title>jquery、ScriptManager调用WebService</title>
      9     <script src="../js/jquery-1.8.3.min.js"></script>
     10     <script>
     11         //请求类型默认是application/json
     12         function ajaxGo() {//默认返回json
     13             //全路径:命名空间.类名.方法名。不管参数名,按照顺序匹配。
     14             WjjStudy.asmx.info.GetStudent(100, function (result) {
     15                 console.log(result);//默认就是json
     16             }, function () {
     17                 console.error("访问失败。");
     18             });
     19 
     20             WjjStudy.asmx.info.GetStudentJson(100, function (result) {
     21                 console.log(result);//默认就是json
     22             }, function () {
     23                 console.error("访问失败。");
     24             });
     25         }
     26 
     27         //请求类型默认是application/x-www-form-urlencoded; charset=UTF-8
     28         function jqAjaxGo() {//默认返回xml,如何改成json?
     29             //1、返回xml
     30             $.ajax({
     31                 type: 'post',//默认只支持post,如果需要支持get,需要配置web.config
     32                 url: '../asmx/info.asmx/GetStudent',
     33                 async: true,
     34                 data: { "para": 1000 },
     35                 success: function (result) {
     36                     console.log(result);
     37                 },
     38                 error: function () {
     39                     console.error("访问失败。");
     40                 }
     41             });
     42             //2、返回xml
     43             $.ajax({
     44                 type: 'post',//默认只支持post,如果需要支持get,需要配置web.config
     45                 url: '../asmx/info.asmx/GetStudentJson',
     46                 async: true,
     47                 data: { para: 1000 },
     48                 success: function (result) {
     49                     console.log(result);
     50                 },
     51                 error: function () {
     52                     console.error("访问失败。");
     53                 }
     54             });
     55 
     56             //如何换成json?大量的尝试后
     57             //不管有没有配置web.config,使用get方法均报错:尝试使用 GET 请求调用方法“GetStudent”,但不允许这样做。
     58             //所以只能post,不能get。
     59 
     60             $.ajax({
     61                 type: 'post',
     62                 url: '../asmx/info.asmx/GetStudent',
     63                 async: true,
     64                 data: '{para:1000}',
     65                 //1、参数列表必须同名,不区分大小写 PARa也行。不管顺序,按照参数名匹配。
     66                 //2、如果指定contentType: 'application/json;charset=UTF-8',直接写{para:1000}报错->无效的para json基元。需要写成'{}'
     67                 contentType: 'application/json;charset=UTF-8',//指定contentType才有效,dataType不指望。
     68                 dataType: 'json',//期待返回的类型,服务器会先 根据返回的数据推断,如果推断不了才会用这里的dataType。一般而言,都可以根据头信息推断出来,所以这里dataType几乎没用。
     69                 success: function (result) {
     70                     console.log(result);
     71                 },
     72                 error: function () {
     73                     console.error("访问失败。");
     74                 }
     75             });
     76 
     77             $.ajax({
     78                 type: 'post',
     79                 url: '../asmx/info.asmx/GetStudentJson',
     80                 async: true,
     81                 data: '{ para: 1000 }',
     82                 contentType: 'application/json;charset=UTF-8',
     83                 success: function (result) {
     84                     console.log(result);
     85                 },
     86                 error: function () {
     87                     console.error("访问失败。");
     88                 }
     89             });
     90 
     91 
     92         }
     93     </script>
     94 </head>
     95 <body>
     96 
     97     <form id="form1" runat="server">
     98         <%--注册脚本,会生成很多其他js--%>
     99         <asp:ScriptManager ID="clientService" runat="server">
    100             <Services>
    101                 <asp:ServiceReference Path="~/asmx/info.asmx" />
    102             </Services>
    103         </asp:ScriptManager>
    104 
    105         <div id="container">
    106             <input type="button" value="ScripManager Test Ajax" onclick="ajaxGo();" />
    107             <br />
    108             <input type="button" value="jQuery Test Ajax" onclick="jqAjaxGo();" />
    109             <br />
    110         </div>
    111     </form>
    112 </body>
    113 </html>

    执行效果 :

    点击ScriptManager Text Ajax:

    点击jQuery Text Ajax按钮

    注意点1

    webservice默认只支持post请求,如果要支持get请求,需要配置web.config,在system.web节点中加入以下配置

     1 <configuration>
     2     <system.web>
     3         <compilation debug="true" targetFramework="4.0" />
     4         <!--加上以下节点,避免Get请求时(默认只支持HttpPost)报错:因 URL 意外地以“/GetStudent”结束,请求格式无法识别。-->
     5         <webServices>
     6             <protocols>
     7                 <add name= "HttpPost" />
     8                 <add name= "HttpGet" />
     9             </protocols>
    10         </webServices>
    11     </system.web>
    12 
    13 </configuration>

    注意点2

     jQuery在发送ajax请求时,请求类型默认是application/x-www-form-urlencoded; charset=UTF-8,webservice默认则会返回xml格式的字符串,如果我们想返回json格式的怎么搞?

    我在客户端发送Ajax请求时,设置dataType:'json',可惜没用,我猜测它的本质含义是:期待返回的类型,服务器会先 根据返回的数据推断,如果推断不了才会用这里的dataType。一般而言,都可以根据头信息推断出来,所以这里dataType几乎没用。然后在服务器端设置Response.ContentType="application/json",也不奏效。当然了,同时设置也没有结果...

    后来我设置contentType:'application/json',貌似看到了希望,可是报错:无效的para json基元,后来测试(很久时间)发现需要将{para:1000}写成'{para:1000}'才可以。

    注意点3

    设置了contentType:'application/json'可以返回json字符串了,但是只能使用post方法,不管你的web.config是否有配置。否则报错:尝试使用 GET 请求调用方法“GetStudent”,但不允许这样做。

    注意点4

    通过ScriptManager来访问WebService时,查看源文件,会发现给你生成很多的JS,开发虽然是简单了,但是这么多的js一定程度上消耗更多的性能,网页加载的速度变慢、数据量增大不可避免了。所以推荐使用jQuery!

    6、总结

    个人认为最佳模式是jQuery加上WebService,但是我还是习惯于jQuery加上Handler。我觉得这篇文章最有意义的还是如何让返回的xml改成返回json。如果你能够亲自动手做一下,相信会有更深的体会,因为代码里写了较多的注释,会帮助你理解。

    参考链接:ASP.NET 使用Ajax

  • 相关阅读:
    ios端浏览器拍照上传到服务器,图片被旋转90度 php 解决方案
    wgs84 转百度经纬度坐标
    vue 编译大量空格警告问题总结 warning: Replace `↹↹` with `&#183;&#183;`
    微信sdk php签名方法整理
    Vue 使用百度地图组件
    php unicode转字符串
    第十篇、微信小程序-view组件
    第九篇、微信小程序-button组件
    第八篇、微信小程序-progress组件
    第七篇、微信小程序-video组件
  • 原文地址:https://www.cnblogs.com/gagarinwjj/p/jquery_webservice.html
Copyright © 2011-2022 走看看