大多数javascript ajax教程/示例都显示请求只能是相对路径,这意味着无法调用其他Web服务器。我想调用不包含在同一应用程序中且需要具有绝对URL的Web服务。我叫http://192.168.1.62:8080/TRACER-REST-API/webapi/projects/16/releases/2/issues之类的东西,而ajax xhr叫http:// localhost:8080 / app / http://192.168.1.62:8080/TRACER-REST-API/webapi/projects/16/releases/2/issues之类的东西



var XHR = null;

var $ajaxService = (function() {
  function getXHRObject() {

    var xmlHttpObject = null;

    try {
      //for old IE
      xmlHttpObject = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (oldIEException) {

      try {
        // For IE 6.0+
        xmlHttpObject = new ActiveXObject("Microsoft.XMLHTTP");

      } catch (IESixPlusException) {

        xmlHttpObject = false;
      }

    }

    if (!xmlHttpObject && xmlHttpObject !== undefined) {
      // firefox/chrome
      xmlHttpObject = new XMLHttpRequest();
    }
    return xmlHttpObject;
  }

  return {
    call: function makeServerCall(httpMethod, uri, isAsync, headers, postData, responseCallback) {
      console.log(uri);
      XHR = getXHRObject();
      if (XHR != null) {

        XHR.open(httpMethod, uri, isAsync);
        if (headers != null) {
          //XHR.setRequestHeader();
        }
        if (httpMethod === 'POST' && postData !== undefined) {
          XHR.send(postData);
        } else {
          XHR.send();
        }

        XHR.onreadystatechange = responseHandler(responseCallback);

      }
    }


  }

  function responseHandler(callBack) {
    if (XHR.readyState == 4) {

      switch (XHR.state) {
        case 200:
          callBack();
          break;
        case 500:
          throw new Error("Internal Server Error");
        default:
          throw new Error("Error occurred during server call");
      }

    }

  }

})();

最佳答案

Ajax可以使用绝对URL来调用Web服务吗?


是的,如果接收服务器支持跨源方案(例如CORS或JSONP),并且您正确指定了URL。

浏览器具有称为“相同来源保护”的安全功能。默认情况下,此保护允许您仅对与运行Javascript的网页完全相同的“来源”(相同的协议,相同的域,相同的端口)进行Ajax调用。

围绕这种相同的原产地保护有两种方法。


CORS-跨源资源共享是一种方案,接收服务器通过该方案告诉浏览器允许部分或全部跨源请求。如果服务器启用了这种类型的访问,则来自其他域的浏览器网页可能会对此服务进行Ajax调用。 CORS不仅具有全部功能,还具有许多功能,因此,一个站点甚至可以仅启用某些类型的访问权限,或者仅启用来自某些其他站点的访问权限。
JSONP-在CORS出现之前,网络世界提出了一种有点黑的变通方法,称为JSONP。在此方案中,浏览器从所需的主机请求脚本文件(脚本文件不受相同的来源安全限制),然后主机服务器返回浏览器将执行的实际Javascript文件。如果操作正确,执行的脚本可以将结果传回给调用方。 JSONP不是常规的Ajax调用,尽管某些Ajax库(如jQuery)允许您即使在发出JSONP请求时也可以使用其Ajax接口。
代理-相同的来源限制仅是浏览器中的功能,因此服务器可以不受限制地联系其想要的任何域。解决相同来源限制的一种方法是让您自己的服务器(在与网页域匹配的自己的域上)为您发出外部请求(例如代理请求)。您将Ajax呼叫发送到您自己的服务器,要求它为您提出代理请求。然后,您的服务器与外部服务器联系,获取结果并将其作为Ajax响应返回给您。




如果您请求对以下URL的Ajax调用:

http://192.168.1.62:8080/TRACER-REST-API/webapi/projects/16/releases/2/issues

您会看到实际使用的是
http:localhost:8080/app/http://192.168.1.62:8080/TRACER-REST-API/webapi/projects/16/releases/2/issues

然后,您的代码可能出了点问题,因为如果您的代码正确,浏览器将不会自行执行此操作。您可能需要向我们展示您的实际代码,以了解您的代码出了什么问题。如果正确指定,则支持绝对URI。



在您的Ajax代码中,您需要进行一些更改:

1)隐式全局。在此处添加var,这样XHR不会是意外的全局变量,因此如果一次执行多个Ajax调用,则不会有变量冲突:

var XHR = getXHRObject();


2)修复XHR.onreadystatechange。更改此:

XHR.onreadystatechange = responseHandler(responseCallback);


为此,您不必立即调用它,而是要分配一个可以在以后调用的函数:

XHR.onreadystatechange = function() {
    responseHandler(XHR, responseCallback);
}


然后,将额外的XHR参数添加到您的responseHandler()实现中。

3)修正错误处理。从throw函数中对responseHandler()进行操作对您没有好处。这是一个异步回调,并且执行throw只会使XMLHttpRequest基础结构陷入困境。可用于任何有意义的事情也不例外。您可能需要重组代码,以便通过回调将错误传达回调用方。

4)使用已经测试过的Ajax库。在当今时代,我不知道为什么要从头开始编写自己的Ajax包装器。实际上,已经有成千上万种可用,您可以直接使用它们,将其复制到您的项目中,而不必通过自己的代码来解决所有这些类型的问题。如果我个人还没有使用任何支持Ajax的框架,那么我可能会为新的fetch() API获取一个polyfill并使用它,因为这是客户端Ajax的未来,并且它是一个非常干净的API。

10-04 22:52
查看更多