我应该解析服务器上的XML还是提供代理并让浏览器解析它?


11

我需要与第三方API交互。使用此API,我可以从最终用户的浏览器中发出GET请求,并接收XML响应。该数据将在基于浏览器的应用程序中使用,用户可以在该应用程序中进行搜索,使用它来做出决定等。主要问题是大多数浏览器已锁定跨域XML的使用,因此我不能简单地获取API中的XML。

但是,总体数据基本上分为两组。

  1. 第一组数据是公共数据,只需要经常更新一次,因此可以为服务器端的所有用户缓存数据,从而大大减少了通信量。
  2. 第二组数据是私有的,对于每个用户而言都是个体的。此数据还会在API中更频繁地更新。这导致缓存效率大大降低。

出于可伸缩性的原因,我想使服务器的负载尽可能小。

我面前有两个选择:

  1. 提供一个代理,该代理可用于将XML请求路由到第三方服务器,并直接在客户端和第三方API之间来回传递。
  2. 让服务器执行从XML到JSON的转换并去除不必要的信息。从本质上讲,这意味着为我们的服务器创建一个新的API,从而转化为来自第三方API的请求

向用户提供数据的最佳方法是什么?(不必是两个选项之一)


XML源与在浏览器中解释它的代码有什么关系?因为如果您编写了自己的(不受支持的)客户端代码以从某些第三方数据中获取数据,那么我想到的第一件事就是某天该第三方将对XML进行一些细微更改并永久破坏您的应用程序。
SJuan76

第三方已经更新了他们的API版本。他们将旧版本保留了一段时间,使人们可以更新其代码以使用新的API。但是,XML数据的结构一旦定义就没有改变,除了API版本之间。
2014年

1
如果API经常更改,那么可能值得您花时间声明自己的架构并拥有充当中间件的服务,以将数据处理为客户期望的内容。我认为问题归结为“更新客户端或更新服务器哪个更容易?”
Hyperbole 2014年

它不频繁。十年来,它已经改变了一次。
amethystdragon 2014年

Answers:


12

代理选项是最容易实现的选项。您无需进行任何自定义开发,唯一要做的就是设置代理。这也很简单:无需维护其他代码,并且如果API发生更改,则无需进行任何更改。

代理将是首选:

  • 如果您需要快速交付工作软件。例如,这是一个不错的选择,如果您打算发布功能,但是在项目的实施阶段发现您不能只是发出跨域AJAX请求。

  • 或者,如果当前的API设计合理:体系结构良好,调用非常清晰,文档完整且易于理解。

  • 或者当前的API可能会更改。如果更改,则只需更改JavaScript实现。如果您不是代理而是解析结果并生成自己的JSON,则存在API更改将需要服务器端代码更改的风险。

另一方面,解析结果有利于在客户端完全抽象API。这是一个较慢的选择,因为它需要设计新的接口(如果原始API的设计不当)并实现提取,转换和加载功能,但是对于大型项目而言,这可能是一个不错的长期选择。这是首选:

  • 如果您需要其他功能。您可以利用原始API中未提供的各种功能,例如在普通代理服务器不支持的级别上缓存加密或其他身份验证模型。

    例如,如果AJAX请求数量成为问题,或者双向通信模型有意义,则可以实现Web套接字。

  • 或者,如果当前的API设计不当。就像外观模式一样,这种方法使您可以重新设计API。如果原始版本较差,那么拥有立面可以解决传统API原始作者做出的错误设计选择。您可以在较大的部分(例如API的整体体系结构)上表现良好,还可以在细节(例如参数名称或错误消息)上表现良好。

    尽管有时不可能修改现有的API,但是拥有立面可以使用一段简洁的代码来工作,该代码抽象出原始设计中的缺点和错误。

  • 或者当前的API可能会更改。实际上,如果API随时间变化,则您可能更愿意更改服务器端代码而不是JavaScript,同时不影响外观的公共接口。可能是因为您对服务器端编程更有经验,或者因为您知道更多用于服务器端重构的工具,或者因为您的项目中处理服务器端代码版本控制更加容易,所以可能更容易。

您可能会注意到,我省略了有关JSON,性能,缓存等的讨论。这是有原因的:

  • JSON与XML:由您选择合适的技术。您可以通过客观地衡量JSON上XML的过热,序列化数据所花费的时间以及简化分析的过程来实现。

  • 性能:对不同的实现进行基准测试,选择最快的实现,然后对其进行概要分析,并根据概要分析器的结果对其进行优化。当您达到非功能性要求中指定的性能时,请停止。

    另外,了解您要达到的目标。相互之间有几个部分相互影响:原始API,服务器与API之间的带宽,服务器的性能,服务器与最终用户之间的带宽以及其计算机的性能。如果系统要求您在30毫秒内获得对请求的响应,但原始API会花费40毫秒。处理请求,无论您做什么,都将无法获得所需的性能。

  • 缓存:缓存是使您的Web应用程序感觉更快,减少带宽等的技术之一。

    1. 考虑到正确设置HTTP标头通常很棘手,请确保还使用客户端缓存(服务器端缓存不会减少您与客户之间的带宽使用)。

    2. 确保正确确定要缓存的内容,使缓存失效的时间和时间:如果产品说明在10秒钟前更改,但是电子商务网站的客户仍然看到旧版本,就可以了。如果所有者更改了描述,提交了描述,但由于缓存而仍然看到先前的变体,这将成为问题。

    3. 不要只专注于缓存。例如,缩小也很重要。减少请求的数量也可能是有益的。


1
+1我犹豫了一下是否应该提及缓存,最后决定反对缓存。仍然值得提出,很好。
JensG 2014年

7

有一个第三个你可能没见过的选项:跨源资源共享(CORS)

CORS标准通过添加新的HTTP标头来工作,这些标头允许服务器将资源提供给允许的原始域。浏览器支持这些标头,并遵守它们建立的限制。

示例:假设您的网站是http://my-cool-site.com,并且您在域http://third-party-site.com上拥有第三方API ,您可以通过AJAX访问该API 。

并假设您在my-cool-site.com服务器上创建的页面已向Third-party-site.com请求。通常,根据“ 相同来源安全策略”,用户浏览器将拒绝对您自己的域/子域以外的任何其他站点的AJAX呼叫。但是,如果浏览器和第三方服务器支持CORS,则会发生以下情况:

  • 浏览器会将以下HTTP标头发送到third-party-site.com

    Origin: http://my-cool-site.com
  • 如果第三方服务器接受来自您域的请求,它将使用以下HTTP标头进行响应:

    Access-Control-Allow-Origin: http://my-cool-site.com
  • 要允许所有域,第三方服务器可以发送以下标头:

    Access-Control-Allow-Origin: *
  • 如果不允许您的站点,浏览器将抛出错误。

如果客户端具有支持CORS的相当现代的浏览器,并且您的第三方服务器也支持CORS,则可以通过对代码进行少量更改来使用它。

在CORS上找到了一个很好的解释,在该解释上,您还会找到另一种方法:JSONP。但是JSONP将需要对您的代码进行大量更改。

要发出CORS请求,您只需XMLHttpRequest在Firefox 3.5 +,Safari 4+和Chrome XDomainRequest中使用IE8 +中的对象。使用XMLHttpRequest对象时,如果浏览器发现您正在尝试进行跨域请求,它将无缝触发CORS行为。

这是一个JavaScript函数,可帮助您创建跨浏览器的CORS对象。

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        // XHR has 'withCredentials' property only if it supports CORS
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){ // if IE use XDR
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

由于您说“大多数浏览器已锁定跨域XML的使用”,所以我猜您的第三方服务器可能不支持CORS。然后,您必须找到替代方法。



1
您可以尝试总结链接中的内容吗?链接容易产生链接腐烂,因此并不是在SE上传达信息的最佳方法:)
Ampt 2014年

遗憾的是,第三方服务器不支持CORS。
amethystdragon 2014年

4

出于可伸缩性的原因,我想使服务器的负载尽可能小

我认为这或多或少都指向答案。是否向客户端提供预处理数据主要取决于:

  1. 交通方面的差异
  2. 处理的性能影响
  3. 不同数据格式对客户端的影响

如果XML比较小或只有几个请求,则将其转发给客户端而忘记它可能是有意义的。当预处理后的数据仍然占原始数据的很大一部分时,或者如果客户端无法从其他数据格式(例如JSON)中获利不多,也是如此。

但是,如果客户端难以处理大型XML数据集,或者如果客户端仅需要原始XML数据的一小部分,则在服务器端进行一些预处理可能是有意义的。

最后,扩展服务器要比扩展客户端/浏览器或可用带宽容易。一句话,它取决于系统中瓶颈的位置。


+1,然后添加-测试不同情况下的性能。
SeraM 2014年

0

我的选择是将选项2缓存并压缩(丢弃不必要的信息)并将gzip结果存储到客户端浏览器。因为浏览器通常不是高端CPU,并且服务器到浏览器的网络线路容量有限。我说的是移动客户端。如果您不打算支持移动客户端,请选择更简单的选项,例如一些Google:CORS proxy

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.