• 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
  • 相关阅读:
    js数组的用法以及数组根据下标(数值或字符)移除元素
    组件创建、组件注册方式
    vue.runtime.esm.js:593 [Vue warn]: Invalid prop: custom validator check failed for prop "value".报错解决
    uni-app 子组件如何调用父组件的方法
    wap2app(十)--wap2app 添加原生底部导航,添加原生标题栏,填坑
    wap2app(九)-- 使用mui.previewImage之后,页面a链接不能跳转
    wap2app(八)-- iphoneX 底部导航的兼容问题
    wap2app(七)-- 长按保存图片
    我的新书《Android App开发从入门到精通》终于出版啦
    Android微信登录、分享、支付
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3461008.html
Copyright © 2020-2023  润新知