zoukankan      html  css  js  c++  java
  • 调用远程服务的几种实现方式

    谈一谈调用远程服务的几种实现方式

    也许在我们过往的项目开发过程当中,或多或少都会遇到过针对于现有系统信息进行整合,使用的需求,或是调用人家接口或是给人家提供服务,今天就简单的和大家一起分享一些可用的远程调用服务的方法:

    1.webservice方法

     Web Service 是一种新的web应用程序分支,他们是自包含、自描述、模块化的应用,可以发布、定位、通过web调用。Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。 
      实际上,WebService的主要目标是跨平台的可互操作性。为了达到这一目标,WebService完全基于XML(可扩展标记语言)、XSD(XMLSchema)等独立于平台、独立于软件供应商的标准,是创建可互操作的、分布式应用程序的新平台。

    我相信大家都会有很多使用webservice的经验,首先说一下在web端调用同域下的webservice:

    新建一个webservice,默认生成一个helloWord方法:

        [WebMethod]
        public string HelloWorld() {
            return "Hello World";
        }

    之后我没在web端调用此服务:

    复制代码
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script src="jquery.js" type="text/javascript"></script>
    
        <script type="text/javascript">
            $(function () {
                $('#a_post').click(function () {
                    postFun();
                });
            });
    
            function postFun() {
                $.ajax({
                    type: "POST",  //访问WebService使用post方式请求
                    contentType: "application/xml",   //WebService会返回json类型
                    url: "http://localhost:1719/testaaa/MyWebService.asmx/HelloWorld", //调用WebService的地址和方法名称组合
                    dataType: "xml",
                    success: function (data) {
                        var html;
                        if (typeof data == "string") {
                            html = new ActiveXObject("Microsoft.XMLDOM");
                            html.loadXML(data);
                        }
                        else {
                            html = data;
                        }
                        var $result = $(html).find("string");
                        var result = $result.text();
                        alert(result);
                    }
                })
            }
        </script>
    </head>
    <body>
    <input type="button" id="a_post" value="获取"/>
    </body>
    </html>
    复制代码

    于是我们可以得到如下:

    说明我们在web端调用同域下webservice成功。

    于是我们会想是否可以以这种方法调用远程(不同域)下的webservice呢?

    我明确的告诉你非常不容易,我一般的处理方式是在C#后台代码中调用这个服务,web端调用同域下的那个调用远程服务的后台服务就可以了,这其实是一种服务代理的方法,如果大家有什么好的实现web端调用远程webservice的方法,希望大家能够告诉我哦。

    于是大家就会想:难道真的没有实现跨域调用服务的方法了吗?

    方法还是有的,听我慢慢道来:

    2:Jsonp

    什么是JSONP  JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

    Jsonp原理:

    由于我们知道<script>标签是可以跨域的,所以我们就以动态生成<script>脚本的形式实现跨域请求:

    首先在客户端注册一个callback, 然后把callback的名字传给服务器。

    此时,服务器先生成 json 数据。 

    然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

    最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

    客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

    由于jsonp传送的形式是json形式,所以我们修改远程的服务:

    复制代码
    using System;
    using System.Web;
    
    public class Handler : IHttpHandler {
    
        public void ProcessRequest(HttpContext context) {
            context.Response.ContentType = "text/plain";
            string callback = context.Request["callback"];
            string response = string.Format("'value1':'{0}','value2':'{1}'", context.Request.QueryString["p1"], context.Request.QueryString["p2"]);
            string call = callback + "({" + response + "})";
            context.Response.Write(call); 
        }
     
        public bool IsReusable {
            get {
                return false;
            }
        }
    
    }
    复制代码

    web端调用:

    复制代码
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script src="jquery.js" type="text/javascript"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                $('#a_post').click(function () {
                    postFun();
                });
            });
    
            var postFun = function () {
                jQuery.ajax({
                    type: "get",
                    //url: "Jsonp_learn.aspx",
                    url: "http://localhost:1719/testaaa/Handler.ashx",
                    dataType: "jsonp",
                    jsonp: "callback",
                    data: "p1=1&p2=2",
                    success: function (msg) {
                        alert("value1:" + msg.value1 + " value2:" + msg.value2);
                    }
                });
            }
        </script>
    </head>
    <body>
    <input type="button" id="a_post" value="获取"/>
    </body>
    </html>
    复制代码

    实现的结果:

    OK,至此我们已经可以实现了我们的一些要求,当然程序员的特点就是永远希望找到最好的东西,并且与一切不简单,不美好的东西作斗争,我们思考一下以上两种实现方法的特点:

    webservice:是以soap协议,xml形式调用的,web端调用我们需要将结果处理成xml;

    jsonp:这是程序员思考的结晶,可是并没有一些官方的标准;

    其实我们回想:何必这么麻烦不就是请求一个结果吗,一个字符串不久可以了?

    3.restful

    RESTful Wcf是一种基于Http协议的服务架构风格。 相较 WCF、WebService 使用 SOAP、WSDL、WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求。

    RESTful的几点好处:

    1、简单的数据通讯方式,基于HTTP协议。避免了使用复杂的数据通讯方式。

    2、避免了复杂的客户端代理。

    3、直接通过URI资源定向即可把服务暴露给调用者。

    REST 架构风格的流行。REST是一种简洁的设计风格,通过URL来设计系统,以URI来抽象各种资源,以HTTP协议的PUT,DELETE,GET,POST来对应对资源的各种操作。

    于是我们决定用这种:既简单,由有一定的规范值得参考:

    我们的实现可以依照wcf,具体实现大家可以google之,我们简单说一下.net的实现restful的比较好的方法webAPI:

    我们通过vs傻瓜式的就建立了一个webapi:

    Model:

    public class TestUseMode
        {
            public string ModeKey{get;set;}
            public string ModeValue { get; set; }
            
        }

    Controller:

    MVC WebAPI中的Controllers和普通MVC的Controllers类似,不过不再继承于Controller,而改为继承API的ApiController,一个Controller可以包含多个Action,这些Action响应请求的方法与Global中配置的路由规则有关,在后面结束Global时统一说明.

    复制代码
     public class TestController : ApiController
        {
            public static List<TestUseMode> allModeList = new List<TestUseMode>();
    
    
    
            public IEnumerable<TestUseMode> GetAll()
            {
                return allModeList;
            }
    
            public IEnumerable<TestUseMode> GetOne(string key)
            {
                return allModeList.FindAll((mode) => { if (mode.ModeKey.Equals(key)) return true; return false; });
            }
    
            public bool PostNew(TestUseMode mode)
            {
                allModeList.Add(mode);
                return true;
            }
    
            public int Delete(string key)
            {
                return allModeList.RemoveAll((mode) => { if (mode.ModeKey == key) return true; return false; });
            }
    
            public int DeleteAll()
            {
                return allModeList.RemoveAll((mode) => { return true; });
            }
    
            public int PutOne(string key, string value)
            {
                List<TestUseMode> upDataList = allModeList.FindAll((mode) => { if (mode.ModeKey == key) return true; return false; });
                foreach(var mode in upDataList)
                {
                    mode.ModeValue = value;
                }
                return upDataList.Count;
            }
        }
    复制代码

    Global:

    默认情况下,模板自带了两个路由规则,分别对应于WebAPI和普通MVC的Web请求,默认的WebAPI路由规则如下

    1             routes.MapHttpRoute(
    2                 name: "DefaultApi",
    3                 routeTemplate: "api/{controller}/{id}",
    4                 defaults: new { id = RouteParameter.Optional }
    5             );

    简单使用JS调用上面提供的数据接口:

    复制代码
     function getAll() {
     2             $.ajax({
     3                 url: "api/Test/",
     4                 type: 'GET',
     5                 success: function (data) {
     6                     document.getElementById("modes").innerHTML = "";
     7                     $.each(data, function (key, val) {
     8                         var str = val.ModeKey + ': ' + val.ModeValue;
     9                         $('<li/>', { html: str }).appendTo($('#modes'));
    10                     });
    11                 }
    12             }).fail(
    13             function (xhr, textStatus, err) {
    14                 alert('Error: ' + err);
    15             });
    16         }
    17 
    18 
    19 
    20         function add() {
    21 
    22             $.ajax({
    23                 url: "api/Test/",
    24                 type: "POST",
    25                 dataType: "json",
    26                 data: { "ModeKey": document.getElementById("txtKey").value, "ModeValue": document.getElementById("txtValue").value },
    27                 success: function (data) {
    28                     getAll();
    29                 }
    30             }).fail(
    31             function (xhr, textStatus, err) {
    32                 alert('Error: ' + err);
    33             });
    34 
    35         }
    36 
    37         function find() {
    38             
    39             $.ajax({
    40                 url: "api/Test/" + document.getElementById("txtFindKey").value,
    41                 type: 'GET',
    42                 success: function (data) {
    43                     document.getElementById("modes").innerHTML = "";
    44                     $.each(data, function (key, val) {
    45                         var str = val.ModeKey + ': ' + val.ModeValue;
    46                         $('<li/>', { html: str }).appendTo($('#modes'));
    47                     });
    48                 }
    49             }).fail(
    50             function (xhr, textStatus, err) {
    51                 alert('Error: ' + err);
    52             });
    53         }
    54 
    55         function removeAll() {
    56             $.ajax({
    57                 url: "api/Test/",
    58                 type: 'DELETE',
    59                 success: function (data) {
    60                     document.getElementById("modes").innerHTML = "";
    61                     getAll();
    62                 }
    63             }).fail(
    64             function (xhr, textStatus, err) {
    65                 alert('Error: ' + err);
    66             });
    67         }
    68 
    69         function remove() {
    70             $.ajax({
    71                 url: "api/Test/"+document.getElementById("txtRemoveKey").value,
    72                 type: 'DELETE',
    73                 success: function (data) {
    74                     document.getElementById("modes").innerHTML = "";
    75                     getAll();
    76                 }
    77             }).fail(
    78             function (xhr, textStatus, err) {
    79                 alert('Error: ' + err);
    80             });
    81         }
    82 
    83         function update() {
    84             $.ajax({
    85                 url: "api/Test/",
    86                 type: 'PUT',
    87                 dataType: "json",
    88                 data: { "key": document.getElementById("txtUpdateKey").value, "value": document.getElementById("txtUpdateValue").value },
    89                 success: function (data) {
    90                     document.getElementById("modes").innerHTML = "";
    91                     getAll();
    92                 }
    93             }).fail(
    94             function (xhr, textStatus, err) {
    95                 alert('Error: ' + err);
    96             });
    97         }
    复制代码

    这样就实现了最基本的CRUD操作。

    目前来看有这几种比较成熟的方法,个人比较喜欢最后一种。

  • 相关阅读:
    清除浮动(float)的影响
    再说模拟测试
    关于vue移动端 ios 的兼容问题(二)
    微信小程序 开发 坑(3)
    记录开发微信小程序的坑(3)
    记录开发微信小程序的坑(2)
    记录微信小程序开发遇到的坑
    记录git常用命令
    配置vue项目stylus变量遇见的问题
    如何在vue项目打包去掉console
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3380239.html
Copyright © 2011-2022 走看看