使用JSONP或CORS进行跨域JavaScript调用

Ram*_*ams 3 ajax jquery jsonp cors

如何在客户端和服务器中使用jsonp和CORS在网页上实现跨域ajax调用.

例如,www.mytestsite.com要进行ajax调用www.otherdestinationserver.com,如何实现使用JSONPCORS实现?

Ram*_*ams 9

最后,我在研究完所有其他帖子后找到了一些解决方案.我正在为这两种方法写答案.

1.仅在没有CORS的情况下使用JSONP:

如果使用JSONP,则始终需要进行服务器端更改以使用callback方法获取json响应.该callback方法也必须存在于javascript执行中.所以在下面的例子中,当我们调用目标url时,如果我们得到响应myCallBackMethod({ "customerData": { "name": "testName", "age": 26 } }),那么我们必须有一个javascript method名称myCallBackMethod.使用jsonp,cookies can also be shared across domains

  • 在此方法中,无需在目标服务器的响应中设置任何标头以允许请求的域.
  • callback本例中使用的方法是myCallBackMethod.此名称可以是任何名称,除了名称javascriptresponse jsonp string must match

客户/ javascript:

function makeTheCall(queryString) {
    var destinationUrl = "www.otherdestinationserver.com";
    $.ajax({
      type: 'GET',
      url: destinationUrl + queryString,
      dataType: 'jsonp',
      jsonpCallback: 'myCallBackMethod',
      async: false, // this is by default false, so not need to mention
      crossDomain: true // tell the browser to allow cross domain calls.
     // success: successResopnse, jsonpCallback will call the successCallback
     // error: failureFunction jsonp does not support errorCallback. So cannot use this 
    });
  }

  window.myCallBackMethod = function(data) {
   successResponse(data);
  }
  
  successResponse = function(data) {
  //functionality goes here;
  }
  
  // the json response from the server when calling the url must be in the below format only.
  
  myCallBackMethod({ "customerData": { "name": "testName", "age": 26 } })
Run Code Online (Sandbox Code Playgroud)

2.仅在没有JSONP且没有URL REWRITES的情况下使用CORS:

如果使用CORS,则始终存在need to make changes on server and client/javascript.在这种方法中,no need to get any callback方法作为json响应的一部分.回应must be a pure json.但是,在目标服务器上进行适当的代码更改以允许请求通过.所以需要headerresponse对象中设置.

客户/ javascript:

function makeTheCall(queryString) {
    var destinationUrl = "www.otherdestinationserver.com";
    $.ajax({
      type: 'GET',
      url: destinationUrl + queryString,
      dataType: 'json', // use json only, not jsonp
      crossDomain: true, // tell browser to allow cross domain.
      success: successResopnse,
      error: failureFunction
    });
  }
  
  successResponse = function(data) {
  //functionality goes here;
  }

  failureFunction = function(data) {
  //functionality goes here;
  }
Run Code Online (Sandbox Code Playgroud)

在服务器上,添加以下标头.

httpServletResponse.setHeader("Access-Control-Allow-Origin", "*"); // Here need to give the origin url (the url in the address bar of the page which is making request). Using * means allow any value
Run Code Online (Sandbox Code Playgroud)
  • 但是,将上面的代码添加到服务器后,服务器和请求的页面之间不会共享任何cookie.为了在请求的页面和服务器上获取cookie,我们需要在客户端和服务器上添加以下属性.

在客户端/ javascript上:

xhrFields: {
    'withCredentials': true // tell the client to send the cookies if any for the requested domain
    }
Run Code Online (Sandbox Code Playgroud)

在服务器上:

httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
Run Code Online (Sandbox Code Playgroud)
  • 这些更改允许客户端和服务器共享cookie.
  • 但是,如果Access-Control-Allow-Credentials在响应中使用标头,则标头的值会受到限制Access-Control-Allow-Origin.它应该never be * if we want to use Access-Control-Allow-Credentials header.因此,给出确切的域名.

服务器更新:

httpServletResponse.setHeader("Access-Control-Allow-Origin", "www.mytestsite.com"); // Give the origin url (the url in the address bar of the page which is making request).
Run Code Online (Sandbox Code Playgroud)

最终客户端/ javascript :(仅限CORS方法)

function makeTheCall(queryString) {
    var destinationUrl = www.otherdestinationserver.com;
    $.ajax({
      type: 'GET',
      url: destinationUrl + queryString,
      dataType: 'json', // use json only, not jsonp
      crossDomain: true, // tell browser to allow cross domain
      xhrFields: {
         'withCredentials': true // tell the client to send the cookies if any for the requested domain
      },
      success: successResopnse,
      error: failureFunction
    });
  }
  
  successResponse = function(data) {
  //functionality goes here;
  }

  failureFunction = function(data) {
  //functionality goes here;
  }
Run Code Online (Sandbox Code Playgroud)

最终服务器代码:(仅限CORS方法)

httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Origin", "www.mytestsite.com");
Run Code Online (Sandbox Code Playgroud)

3.仅使用CORS使用URL REWRITE FILTER设置RESPONSE HEADERS:

如果应用程序使用url重写过滤器(主要是所有Web应用程序都使用),这将使实现更容易.在上面的方法2中,不是遵循最终服务器代码:(仅CORS方法),而是按照以下URL更改xml(url重写过滤器).

如何使用urlrewritefilter将我们从请求获得的origin或referer值设置到response-header中

下面粘贴相同的代码以供快速参考.

<rule enabled="true" match-type="regex">
<name>Enabling CORS Headers</name>
<from>^/path/someMorePath.*$</from>
<condition name="origin" operator="equal">([a-z]+)</condition>
<set type="response-header" name="Access-Control-Allow-Origin">%1</set>
<set type="response-header" name="Access-Control-Allow-Credentials">true</set>
Run Code Online (Sandbox Code Playgroud)