2

My SharePoint client JavaScript is calling an external REST API URL, using the code pattern below

$.ajax({
  type: "POST",
  url: 'https:\\theexternal.domain......,
  contentType: "application/json",
  headers: {
      'Accept' : "application/json, */*;",
      'Authorization': 'Basic ' + btoa(username + ':' + password)  
  },
  data: JSON.stringify({
      .
      .
      .
  }),
   success: success,
   error: error
}); 

We have changed the web.xml configuration file of the external domain server, to include the code:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping> 

as per the directions on https://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter.

However, the AJAX POST is still returning the error

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https:\theexternal.domain...... This can be fixed by moving the resource to the same domain or enabling CORS.

What have we missed?

7

Modern browsers block cross-domain JavaScript requests by design - it's a security feature, not a bug. There exists workarounds for this, which can be used only if you have an access to configure the external domain:

The theexternal.domain source needs to explicitly enable your request by including Access-Control-Allow-Origin: http://siteMakingTheCall.domain to the HTTP header.

There exists more broader explanation of this in e.g. these sources:


Edit: Using Apache Tomcat as in your case, the configuration might be a bit different. The "minimal configuration" as you seem to have used based on your question should be expanded to include an <init-param>-block for cors.allowed.origins to actually allow the request coming from outside. So, the complete configuration would be the following:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

However, I'd strongly suggest to replace the * to only include the SharePoint's host. If you have multiple hosts to be added, do it by comma-separating - e.g. sp-host1.com, sp-host2.com

  • According to the tomcat website, if I've set up the CorsFilter definition, it draws in all the subsequent defaults: that include: cors.allowed.origins A list of origins that are allowed to access the resource. A * can be specified to enable access to resource from any origin. Otherwise, a whitelist of comma separated origins can be provided. Eg: w3.org, apache.org. Defaults: * (Any origin is allowed to access the resource). So, my understanding is that this code will allow theexternal.domain to accept '*' as an origin. Or have I missed something? – southskies Jun 28 '17 at 6:22
  • So, is this filter automatically adding in cors.allowed.origins : * to the headers of any incoming request? Or is it telling the server to just ignore any headers as everything is allowed to come through? – southskies Jun 28 '17 at 6:44
  • * enables any origin to request the source. I'll update in a minute the answer to give a suggestion. – moe Jun 28 '17 at 7:07
  • I can't thank you enough for your help. Yes, this is the solution. Works wonderfully. Many, many thanks! – southskies Jun 28 '17 at 8:06
  • @southskies glad to help. One more thing: you should mark it as an answer to promote the visibility for others looking for help with the same issue. – moe Jun 28 '17 at 8:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.