zoukankan      html  css  js  c++  java
  • ajax调用webservice

    $.ajax()调用webservice

     

     

    常规请求基本格式

     

    1         [WebMethod]
    2         public string SayHello(string name)
    3         {
    4             return "Hello " + name;
    5         }
    复制代码
     1             $.ajax({
     2                 url: "/CommonService.asmx/SayHello",
     3                 type: "Post",
     4                 dataType: "json",
     5                 contentType: "application/json; charset=utf-8",
     6                 data: "{name:'Varchar32'}",
     7                 success: function (data) {
     8                     alert(data.d);
     9                 },
    10                 error: function (data) {
    11                     //200的响应也有可能被认定为error,responseText中没有Message部分
    12                     alert($.parseJSON(data.responseText).Message);
    13                 },
    14                 complete: function (data) {
    15                     ;//after success or error
    16                 }
    17             });
    复制代码

    其中几个参数的含义

      type:请求方式,又称Method

      dataType:预期返回类型(The type of data that you're expecting back from the server)

      contentType:发送到服务器的数据的编码类型(When sending data to the server, use this content type)

      data:发送到服务器的数据

    返回各种类型的数据

     

     1、返回string

    1         [WebMethod]
    2         public string HelloWorld()
    3         {
    4             return "Hello World";
    5         }
    1     //js的其他部分略
    2     success: function (data) {
    3         $(".ajaxresult div:eq(0)").html("返回数据的类型为:" + typeof(data.d));
    4         $(".ajaxresult div:eq(1)").html("内容为:" + data.d);
    5     }    

    浏览器看到的结果

    另附上采用text格式调用的代码

    复制代码
     1             $.ajax({
     2                 url: "/CommonService.asmx/HelloWorld",
     3                 type: "Post",
     4                 dataType: "text",
     5                 data: {},
     6                 success: function (data) {
     7                     $(".ajaxresult div:eq(0)").html("返回数据的类型为:" + typeof (data));
     8                     $(".ajaxresult div:eq(1)").html("内容为:" + data);
     9                 }
    10             });
    复制代码

     2、返回int

    1         [WebMethod]
    2         public int HelloWorld()
    3         {
    4             return 1;
    5         }

    js部分略

    浏览器看到的结果

    3、返回数组(List或Array)

    1         [WebMethod]
    2         public List<string> HelloWorld()
    3         {
    4             return new List<string>() { "Frozen_Zhang","Varchar32"};
    5         }
    复制代码
     1             //js的其他部分略
     2             success: function (data) {
     3                     $(".ajaxresult div:eq(0)").html("返回数据的类型为:" + typeof (data.d));
     4                     var str = "";
     5                     $.each(data.d, function (index, val) {
     6                         str += "第" + index + "项:" + val + " ;";
     7                     });
     8                     str = str.substring(0,str.length - 1);
     9                     $(".ajaxresult div:eq(1)").html("内容为:" + str);
    10                 }
    复制代码

    浏览器看到的结果

    4、返回自定义类

    1     public class Person 
    2     {
    3         public string Name { get; set; }
    4         public bool Gender { get; set; }
    5     }
    复制代码
    1         [WebMethod]
    2         public Person HelloWorld()
    3         {
    4             return new Person() { 
    5                 Name = "Varchar32",
    6                 Gender = true
    7             };
    8         }
    复制代码
    复制代码
    1                 //js的其他部分略
    2                 success: function (data) {
    3                     $(".ajaxresult div:eq(0)").html("返回数据的类型为:" + typeof (data.d));
    4                     $(".ajaxresult div:eq(1)").html("内容为:姓名" +  data.d.Name + ",性别" + (data.d.Gender ? "男" : "女"));
    5                 }
    复制代码

    浏览器看到的结果

    5、返回自定义类的集合

    复制代码
     1         [WebMethod]
     2         public List<Person> HelloWorld()
     3         {
     4             return new List<Person>(){
     5                 new Person() { 
     6                     Name = "Varchar32",
     7                     Gender = true
     8                 },
     9                 new Person(){
    10                     Name = "Frozen_Zhang",
    11                     Gender = true
    12                 }
    13             };
    14         }
    复制代码
    复制代码
     1          //js的其他部分略
     2                 success: function (data) {
     3                     $(".ajaxresult div:eq(0)").html("返回数据的类型为:" + typeof (data.d));
     4                     var str = "";
     5                     $.each(data.d, function (index, val) {
     6                         str += "第" + index + "项:" + "姓名" + val.Name + ",性别" + (val.Gender ? "男" : "女") + " ;";
     7                     });
     8                     str = str.substring(0, str.length - 1);
     9                     $(".ajaxresult div:eq(1)").html("内容为:" + str);
    10                 }
    复制代码

    浏览器看到的结果

    6、返回Dictionary

    复制代码
    1         [WebMethod]
    2         public Dictionary<string,string> HelloWorld()
    3         {
    4             //键必须是string类型
    5             var dict = new Dictionary<string, string>();
    6             dict.Add("1","Varchar32");
    7             dict.Add("2", "Frozen_Zhang");
    8             return dict;
    9         }
    复制代码
    复制代码
     1                 //js的其他部分略
     2                 success: function (data) {
     3                     $(".ajaxresult div:eq(0)").html("返回数据的类型为:" + typeof (data.d));
     4                     var str = "";
     5                     $.each(data.d, function (key, val) {
     6                         str += "键:" + key + ",值:" + val + " ;";
     7                     });
     8                     str = str.substring(0, str.length - 1);
     9                     $(".ajaxresult div:eq(1)").html("内容为:" + str);
    10                 }
    复制代码

    浏览器看到的结果

    7、返回DataSet

    复制代码
     1         [WebMethod]
     2         public DataSet HelloWorld()
     3         {
     4             var ds = new DataSet();
     5             var dt = new DataTable();
     6             dt.Columns.Add("Name");
     7             dt.Columns.Add("Gender");
     8             dt.Rows.Add("Varchar32", true);
     9             dt.Rows.Add("Frozen_Zhang", true);
    10             ds.Tables.Add(dt);
    11             return ds;
    12         }
    复制代码
    复制代码
     1             //此处采用xml格式调用
             $.ajax({
    2 url: "/CommonService.asmx/HelloWorld", 3 type: "Post", 4 dataType: "xml",
    7 data: {}, 9 success: function (data) { 10 var str = ""; 11 $.each($.find("Table1", data), function () { 12 str += $(this).find("Name").text() + (Boolean($(this).find("Gender").text()) ? "男" : "女") + ";"; 13 }); 14 15 str = str.substring(0, str.length - 1); 16 $(".ajaxresult div:eq(1)").html("内容为:" + str); 17 } 18 });
    复制代码

    浏览器看到的结果

     

     *、用xml格式调用比较简单,用json格式要引用Microsoft.Web.Preview.dll库,还要在web.config中添加一大串,比较麻烦

    跨域请求

     

    1、原理

      javascript的同源策略(Same-Origin Policy):js不能访问不在同一域下的页面内容,因此XmlHttpRequest只能请求在同一源下的资源

        但script标签的src属性不受同源策略的影响

    复制代码
    1     <script type="text/javascript" id="script1">
    2         funccallback = function (data) {
    3             alert(data);
    4         }
    5     </script>
    6     <script type="text/javascript" id="script2">
    7         funccallback("Varchar32");
    8     </script>
    复制代码

    上面的脚本肯定没问题

    现在假设另一个源url.com下有一js脚本scirpt.js,只有一句

      funccallback("Varchar32");

    我将script2改成下面一段带src属性的脚本

    1     <script type="text/javascript" src="http://www.url.com/scirpt.js">
    2     </script>

    也会顺利弹窗

    随意改变http://www.url.com/scirpt.js里给funccallback传递的参数,就是说scirpt1中的funccallback接受到了其他源下的动态数据

    $.ajax()就是对这种请求形式进行了封装,向其他源的服务器发送一个GET请求,返回一个指定格式的数据

    这种格式就是JSONP格式:回调函数名(json格式的动态数据)

    2、请求ashx

    复制代码
     1      public void ProcessRequest(HttpContext context)
     2         {
     3             string callback = context.Request.QueryString["callback"];
     4             var name = context.Request.QueryString["name"];
     5             string json = "{"name":"" + name + "","gender":"" + "" + ""}";
     6             //JSONP格式:回调函数名(json格式参数)
     7             //括号后不要加分号
     8             string result = callback + "(" + json + ")";
     9             context.Response.ContentType = "application/json";
    10             context.Response.Write(result);
    11         }
    复制代码
    复制代码
     1         //回调函数funccallback,回调函数的定义不要放在 $(function () {    });里
     2         function funccallback(data) {
     3             alert("in callback" + ":" + data.name + ", 性别" + data.gender);
     4         }
     5 
     6         $.ajax({
     7             url: "http://localhost:12500/handler1.ashx?callback=?",
     8             dataType: "jsonp",
     9             //jsonpCallback: "funccallback",
    10             //说明:1、未指定jsonpCallback项则会产生一个随机回调函数名,是由ajax方法随机生成,而不是服务器;2、jsonpCallback项和url的callback参数不可同时指定(callback参数指定为'?'除外);3、随机函数名就意味着成功返回后只会执行success,指定回调函数反而会显得多余
    11             data: { name: "Varchar32" },
    12             //执行顺序是success在回调函数之后
    13             success: function (data) {
    14                 //data,同回调函数中的data,就是在服务器端为回调函数传递的json格式参数
    15                 alert("in success" + ":" + data.name + ", 性别" + data.gender);
    16             }
    17         });
    复制代码

    脚本执行结果为浏览器弹出确认框:‘in success:Varchar32, 性别男’

    firefox浏览器中看到的响应

      

    3、请求webservice

    复制代码
    1         [WebMethod]
    2         public void GetGenderByName(string callback, string name)
    3         {
    4             var json = "{"name":"" + name + "","gender":"" + "" + ""}";
    5             string result = callback + "(" + json + ")";
    6             HttpContext.Current.Response.ContentType = "application/json";
    7             HttpContext.Current.Response.Write(result);
    8             HttpContext.Current.Response.End();
    9         }
    复制代码
    复制代码
     1         //回调函数funccallback,回调函数的定义不要放在 $(function () {    });里
     2         function funccallback(data) {
     3             alert("in callback" + ":" + data.name + ", 性别" + data.gender);
     4         }
     5 
     6         $.ajax({
     7             url: "http://localhost:12500/CommonService.asmx/GetGenderByName?callback=?",
     8             dataType: "jsonp",
     9             //jsonpCallback: "funccallback",
    10             data: { name: "Varchar32" },
    11             success: function (data) {
    12                 alert("in success" + ":" + data.name + ", 性别" + data.gender);
    13             }
    14         });
    复制代码

    4、$.getJSON

    复制代码
    1         $.getJSON("http://localhost:12500/CommonService.asmx/GetGenderByName?name=Varchar32&callback=?",
    2             function (data) {
    3                 alert("in success" + ":" + data.name + ", 性别" + data.gender);
    4             }
    5         ); 
    复制代码

    5、返回复杂类型

    复制代码
     1      public void ProcessRequest(HttpContext context)
     2         {
     3             string callback = context.Request.QueryString["callback"];
     4             var name = context.Request.QueryString["name"];
     5 
     6             var person = new Person()
     7             {
     8                 Name = name,
     9                 Gender = true
    10             };
    11 
    12             DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
    13             MemoryStream ms = new MemoryStream();
    14             ser.WriteObject(ms, person);
    15             string jsonString = Encoding.UTF8.GetString(ms.ToArray());
    16             ms.Close();
    17 
    18             string json = jsonString;
    19 
    20             //JSONP格式:回调函数名(json格式参数)
    21             //括号后不要加分号
    22             string result = callback + "(" + json + ")";
    23             context.Response.ContentType = "application/json";
    24             context.Response.Write(result);
    25         }
    复制代码

    常见问题

    1、webservice定义了几个方同名的法时,ajax请求会被同名方法中的最后一个响应,而不是根据参数自动匹配

    2、Method use ‘Get’,返回xml or text,要在Web.config中添加节点

      <webServices><protocols><add name= "HttpGet"/></protocols></webServices>

    3Method use ‘Get’,返回json,要给Webservice的方法添加UseHttpGet特性

          [ScriptMethod(UseHttpGet=true)]

    4dataType并不是服务器返回数据的类型(格式),just expecting。看下面的几种请求方式

      第一种:一般方式

    复制代码
     1             $.ajax({
     2                 url: "/CommonService.asmx/SayHello",
     3                 type: "Post",
     4                 dataType: "json",
     5                 contentType: "application/json; charset=utf-8",
     6                 data: "{ name: 'Varchar32' }",
     7                 success: function (data) {
     8                     alert(data.d);
     9                 },
    10                 error: function (data) {
    11                     alert(data);
    12                 }
    13             });
    复制代码

      结果弹出确认框‘Hello Varchar32’,从firefox看到的结果

      

      

      第二种:省略dataType项,代码略,结果和第一种一样,弹出确认框‘Hello Varchar32’

      第三种:给dataType指定为‘text’,代码略,弹出确认框‘undefined’,但返回结果从firefox看和上面两种第二种请求格式一样

      第四种:给dataType指定为‘xml’,代码略,结果执行了error方法,但返回结果从firefox看和以上几种方式一样(200的响应被认定为了error)

      为什么第二种情况不会报错,第三种明明返回了json格式,但data.d为什么是undefined呢,而第四种请求会被认定为error

      1)认真从firefxo中观察请求头和响应头会发现,响应头的content-Type始终是‘application/json; charset=utf-8’

      

      2)请求头的Accept项有所不同,分别是

        常规格式:

        省略dataType项:

        给dataType指定为‘text’:

        给dataType指定为‘xml’

       3)从jquery官网上找到$.ajax()的选项content-Type定义中的这么一句

          If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent)

        意思差不多就是:如果指定了‘content-Type’,不管有没有数据,始终发送到服务器

        如果仅仅是提交的数据的类型(格式),为什么没数据还要发送到服务器呢

       4)修改success方法

    1            success: function (data) {
    2                  alert(typeof(data)); //alert data 的类型
    3                  alert(data.d);
    4             },

        结果分别是:object、object、string、不执行success

        结论:(假设成功返回,状态码200)

           content-Type同时是提交数据和返回数据的类型(格式)。即若指定为‘application/json; charset=utf-8’,则返回类型一定为‘json’,此时dataType可省略;未指定则默认返回的是xml格式的数据

             dataType为预期(expecting)的返回格式(格式比类型更恰当),若实际返回格式与预期格式相同 或 预期格式在js中对应的数据类型为String(text、html格式对应的为String,json、xml对应Object),则执行succes,否则被认定为error。第四种请求方式,返回格式为json,预期格式为xml,两种格式不同 且 预期格式在js中对应的类型为Object,虽然200,依然被认定为error

           success方法获取到的返回数据data的类型为预期返回格式在js中对应的类型(Object或String),第三种请求方式,data的类型为String,内容为‘{"d":"Hello World"}’,对String调用.d,当然是undefined,假设有一句‘alert($.parseJSON(data).d);’,此句会得到想要的结果

           dataType作用:1、判断是success还是error;2、success方法接受到的数据data的类型

    5、content-Type的几种可选类型: text:“text/plain“;    xml:“application/xml“;    json:“application/json“; html:“text/html”;   script:"application/x-javascript"

    6、采用json格式为什么要‘.d’,json格式是一Ojbect,微软框架默认的是{"d":"后台返回的数据"},d属性的值才是后台返回的数据

     

     
     
     
    标签: ajaxjsonpwebservice
  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3461008.html
Copyright © 2011-2022 走看看