ExtJS PUT request to Tomcat server is not allowed - rest

I implemented a grid with records and a form in order to create and update these records. When editing a record and saving it afterwards, the client will go through the following lines:
var form = this.getView().getForm();
var record = form.getRecord();
record.beginEdit();
var updatedRecord = form.getValues();
record.set(updatedRecord);
record.endEdit();
By doing that, the client will send a PUT request to the Tomcat server with the updated parameters inside the body.
The tomcat server allows all HTTP messages as set in the web.xml:
<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>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
When I use a browser plugin in order to send HTTP requests, everything is fine as we can see in this response:
Status Code: 200 OK
Allow: PUT
Content-Language: en
Content-Length: 190
Content-Type: application/json
Date: Mon, 22 May 2017 12:21:40 GMT
Server: Apache-Coyote/1.1
But when ExtJS sends the PUT request, I get the following response:
HTTP/1.1 405 Method Not Allowed
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:1337
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Allow: DELETE,GET,OPTIONS
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1056
Date: Mon, 22 May 2017 11:55:37 GMT
Why does tomcat not allow PUT, GET and POST, if ExtJS sends a PUT request.
When ExtJS sends a POST request, everything works fine and I get the following response:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:1337
Access-Control-Expose-Headers:Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Content-Length:225
Content-Type:application/json
Date:Mon, 22 May 2017 12:59:07 GMT
Server:Apache-Coyote/1.1
What do I have to do to get Tomcat to allow PUT messages?

You have to specify headers in proxy config of store in EXTJS.
proxy: {
headers: {'Content-Type': "application/json" }
...
}
I think by specifying headers your problem should resolve.
I thinks actionMethod also can create issue.
By default extjs's store sends GET request but if you want it to send PUT request then you can specify in actionMethods config
proxy: {
actionMethods: {
read : 'PUT',
create : 'POST',
update : 'PUT',
destroy : 'DELETE'
}
...
}
Please refer link.

Related

Pentaho CDA: Basic Authentication and CORS conflict

Working on a web app which queries Pentaho BI server 7 with a Tomcat 8 inside I'm facing some issues.
First of all to avoid CORS (Cross-origin resource sharing) problems I have added the CORS filter inside the web.xml config file of the tomcat:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Afterwards, everything was fine until it was necessary to get some resources through Pentaho CDA (Pentaho Community Data Access). I've added a Basic Auth header and one line in the plugin settings file (pentaho-solutions/system/cda/settings.xml):
<allow-cross-domain-resources>true</allow-cross-domain-resources>
Every request my aplication does gets the same error:
XMLHttpRequest cannot load http://localhost:8080/pentaho/plugin/cda/api/doQuery?path=/whatever/dashboard.cda&dataAccessId=mdxGetSmth. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:xxx' is therefore not allowed access. The response had HTTP status code 401.
The funny thing is that the same query is working in Postman (of course with the same Basic auth header) just because Postman just jumps over the OPTIONS (preflight) request.
Used Ngnix as Reverse proxy on Apache-Tomcat and resolved this CORS error

BaseX REST API: Set custom HTTP response header

I want to include the following HTTP header to all responses by the BaseX REST API:
Access-Control-Allow-Origin: *
Is this possible?
BaseX uses Jetty below the hood. You can modify the web.xml file to make Jetty send CORS headers, but either
use at least BaseX 8.6.3 which added the jetty-servlets library or
have to add the jetty-servlets jar to your $CLASSPATH (BaseX already ships jetty-servlet, which is a different class; and be sure to fetch the appropriate version matching what's included in BaseX).
Include following directives to the web.xml file:
<web-app>
<!-- add those before the closing web-app tag: -->
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Be aware that Jetty does not seem to support posting a wildcard header Access-Control-Allow-Origin: *: while the default is already
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
(put that into the <filter/> element), Jetty uses this to construct a regular expression and always returns the value of the Origin: request header if matching, but that should also serve you well.
An example request:
$ curl -v -H "Origin: http://foo.example" http://admin:admin#localhost:8984/rest
* Trying ::1...
* Connected to localhost (::1) port 8984 (#0)
* Server auth using Basic with user 'admin'
> GET /rest HTTP/1.1
> Host: localhost:8984
> Authorization: Basic YWRtaW46YWRtaW4=
> User-Agent: curl/7.50.1
> Accept: */*
> Origin: http://foo.example
>
< HTTP/1.1 200 OK
< Content-Type: application/xml; charset=UTF-8
< Content-Length: 152
< Server: Jetty(8.1.18.v20150929)
<
<rest:databases xmlns:rest="http://basex.org/rest" resources="1">
<rest:database resources="1" size="96234589">test</rest:database>
</rest:databases>
* Connection #0 to host localhost left intact
Given this seems a rather reasonable request and thing to do, you might be successful opening an issue to include the library by default, and maybe even enabling CORS by default. (the library is now included by default)

No 'Access-Control-Allow-Origin' header is present on the requested resource - Resteasy

I am working on a webapplication comprises UI-Angular , Server-Java , RestEasy 3.0.9.Final for rest api calls
When i tried to access the rest service from another domain am getting below error
CANNOT LOAD Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
I configured my server side to respond with the cross domain calls and this is working with the GET Call but POST Call is creating ERROR
web.xml
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>com.test.sample.app.CorsFeature</param-value>
</context-param>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.sample.app.Application</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
Service class
#GET
#Path("/getnameAtt")
#Produces(MediaType.APPLICATION_JSON)
public Response getHostnameAttributes() {
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD")
.header("Access-Control-Max-Age", "1209600")
.entity(new TestImpl().getHostNameAttributes())
.build();
}
#POST
#Path("/getSeq")
#Produces(MediaType.APPLICATION_JSON)
public Response getCurrentSequence(String request) {
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD")
.header("Access-Control-Max-Age", "1209600")
.entity(new TestImpl().getCurrentSeq(request))
.build();
}
Since i am new to resteasy not able to figure out why this was not working.
Any help would be greatly appreciated . Waiting for your response.
Thanks
Your resource methods won't get hit, so their headers will never get set. The reason is that there is what's called a preflight request before the actual request, which is an OPTIONS request. So the error comes from the fact that the preflight request doesn't produce the necessary headers.
For RESTeasy, you should use CorsFilter. You can see here for some example how to configure it. This filter will handle the preflight request. So you can remove all those headers you have in your resource methods.
See Also:
HTTP access control (CORS)
Seems your resource POSTmethod won't get hit as #peeskillet mention. Most probably your ~POST~ request won't work, because it may not be a simple request. The only simple requests are GET, HEAD or POST and request headers are simple(The only simple headers are Accept, Accept-Language, Content-Language, Content-Type= application/x-www-form-urlencoded, multipart/form-data, text/plain).
Since in you already add Access-Control-Allow-Origin headers to your Response, you can add new OPTIONS method to your resource class.
#OPTIONS
#Path("{path : .*}")
public Response options() {
return Response.ok("")
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
.header("Access-Control-Max-Age", "2000")
.build();
}
After facing a similar issue, below is what I did :
Created a class extending javax.ws.rs.core.Application and added a Cors Filter to it.
To the CORS filter, I added corsFilter.getAllowedOrigins().add("http://localhost:4200");.
Basically, you should add the URL which you want to allow Cross-Origin Resource Sharing. Ans you can also use "*" instead of any specific URL to allow any URL.
public class RestApplication
extends Application
{
private Set<Object> singletons = new HashSet<Object>();
public MessageApplication()
{
singletons.add(new CalculatorService()); //CalculatorService is your specific service you want to add/use.
CorsFilter corsFilter = new CorsFilter();
// To allow all origins for CORS add following, otherwise add only specific urls.
// corsFilter.getAllowedOrigins().add("*");
System.out.println("To only allow restrcited urls ");
corsFilter.getAllowedOrigins().add("http://localhost:4200");
singletons = new LinkedHashSet<Object>();
singletons.add(corsFilter);
}
#Override
public Set<Object> getSingletons()
{
return singletons;
}
}
And here is my web.xml:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>
<!-- Auto scan rest service -->
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.app.RestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
The most important code which I was missing when I was getting this issue was, I was not adding my class extending javax.ws.rs.Application i.e RestApplication to the init-param of <servlet-name>resteasy-servlet</servlet-name>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.app.RestApplication</param-value>
</init-param>
And therefore my Filter was not able to execute and thus the application was not allowing CORS from the URL specified.

Tomcat7 REST Service with Basic Authentification XMLHttpRequest

I'm just setting up a small TestScenario. I'm exposing a REST Service on Tomcat 7 with Jersey. The service is called by another Javascript/HTML5 Application via XMLHttpRequest.
For testing I just run the REST Service inside my eclipse installation with Tomcat.
Calling the REST Service from JavaScript works fine without any authentication setup.
Now I'm trying to add Basic Authentication mechanism to my REST Services. In the web.xml of my web project i added
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ImageLinksServices</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.xxx.xxx.services</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<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>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Wildcard means whole app requires authentication</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>tomcat1</role-name>
</auth-constraint>
<user-data-constraint>
<!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
Calling the REST URL from Browser works fine. He asks for user and password then the Response of the REST service is displayed.
But when i try to call it from a Javascript with the following snipplet i receive always a 403 error and a warning that
OPTIONS http://localhost:10080/xxxx/rest/fileupload No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access
Code Snipplet i'm currently using:
xhr.open('POST', url, true);
//xhr.open("POST", url, true, "user1", "tomcat1");
xhr.setRequestHeader("Authorization","Basic "+ btoa("user1:tomcat1"));
xhr.withCredentials = "true";
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
var jsonResponse = JSON.parse(xhr.responseText);
What I'm doing wrong ? I'm totally confused why now after adding authentication the Browser complains about No Access Control Header is present. Before adding authentication to the service the call works also with CORS.
What I can see from the HTTP Request that the Basic Authentication Header seems to be set correctly.
Request URL:http://localhost:10080/xxx/rest/fileupload
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:authorization, content-type
Access-Control-Request-Method:POST
Authorization:Basic dXNlcjE6dG9tY2F0MQ==
Connection:keep-alive
Host:localhost:10080
Origin:http://localhost:63342
Referer:http://localhost:63342/xxx/html/index.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Response Headersview source
Content-Length:0
Content-Type:text/plain
Date:Thu, 05 Dec 2013 12:58:46 GMT
Server:Apache-Coyote/1.1
Can anyone help me to understand what I'm doing wrong. I confused if a Tmocat configruation is mssing or my Javascript is wrong.
I don't know if you managed to resolve your issue, but I ran into the same problem and debugged through the org.apache.catalina.filters.CorsFilter to figure out why the request was being forbidden.
According to the W3 CORS Spec Section 6.2 Preflight Requests, the preflight must reject the request if any header submitted does not match the allowed headers.
The default configuration for the CorsFilter cors.allowed.headers (as is yours) does not include the Authorization header that is submitted with the request.
I updated the cors.allowed.headers filter setting to accept the authorization header and the preflight request is now successful.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
</init-param>
</filter>

GWT with XS. No POST, Just OPTIONS. Load cancelled

I have a problem with a GWT Application which is rather simple but using the Cross-Site-Scripting mechanism of gwt in conjunction with the GWT-RPC (Async-Interface).
The Problem is, that the Browser is sending only the OPTIONS command to the RPC-Backend but not POST. Therefore the data never reach the server. This is the capture of the client-server-communication:
From the GWT-Client
OPTIONS /contact/contact/dispatchService HTTP/1.1
Host: svr3.dmz.mycompany.com:8380
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://www.mycompany.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Access-Control-Request-Headers: x-gwt-module-base, x-gwt-permutation, origin, content-type
Accept: */*
Referer: http://www.mycompany.com/contact.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
From the Server
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: POST, TRACE, OPTIONS
Content-Length: 0
Date: Tue, 23 Apr 2013 07:13:06 GMT
But no data are beeing sent via POST.
In my module.gwt.xml I have the following line for using the xs-Linker:
<inherits name="com.google.gwt.core.Core" />
<add-linker name="xs" />
I have also tried xsiframe unfortunately with the same result.
When I directly invoke GWT-Application from the same server without cross-site-scripting everything works fine:
POST /contact/contact/dispatchService HTTP/1.1
Host: svr3.dmz.mycompany.com:8380
Connection: keep-alive
Content-Length: 273
X-GWT-Module-Base: http://svr3.dmz.mycompany.com:8380/contact/contact/
X-GWT-Permutation: 5BE2BF501B916E292DCA5282B8B896AE
Origin: http://svr3.dmz.mycompany.com:8380
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Content-Type: text/x-gwt-rpc; charset=UTF-8
Accept: */*
Referer: http://svr3.dmz.mycompany.com:8380/contact/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __utma=179080955.1318578617.1360141977.1366109245.1366612633.29; __utmc=179080955; __utmz=179080955.1366104741.27.5.utmcsr=www.mycompany.com|utmccn=(referral)|utmcmd=referral|utmcct=/index.html
From the Server
7|0|9|http://svr3.dmz.mycompany.com:8380/contact/contact/|C4C9C36F0F0B498822C3C822496B3301|com.mycompany.contact.client.DispatchService|dispatch|com.mycompany.contact.client.DispatchService$Message/2078545930||lastname#mycompany.com|Direct via
svr3.|givenname|1|2|3|4|1|5|5|6|7|8|9|6|HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: attachment
Content-Type: application/json;charset=utf-8
Content-Length: 12
Date: Tue, 23 Apr 2013 07:15:44 GMT
//OK[[],0,7]
The Webapplication is running on a Tomcat6 behind an Apache2 connected via mod_jk.
Any idea how I can solve this issue?
This is known as a preflight request and is made by the browser when you do a cross-origin request (with a few exceptions for legacy reasons) to first check with the server whether the webapp is allowed to POST.
You have to handle the OPTIONS request on the server-side and respond with the appropriate Access-Control-Allow-Origin header (and possibly Access-Control-Max-Age, Access-Control-Allow-Headers, etc.)
See http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
Note that this will (obviously) only work in browsers that support CORS, which rules out a lot of people (IE only supports CORS starting with IE10, unfortunately not yet mainstream): http://caniuse.com/cors
See also https://developers.google.com/web-toolkit/doc/latest/FAQ_Server#SOP,_GWT,_and_XMLHTTPRequest_Calls
Using the xs linker (BTW, you should prefer the xsiframe linker nowadays, the doc is a little bit out-of-date) only fixes the loading of the script, it doesn't cover the requests to a server. You can use a proxy (servlet, script, server configuration, whatever) on the same origin as the HTML host page that routes the requests to the server where the RPC services are actually deployed; see https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuideRPCDeployment
Based on the Information from Thomas Broyer I managed to resolve the issue by adding a CORS-Support-Filter:
First I added this to my pom.xml:
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>1.3.2</version>
</dependency>
Then added this to my web.xml:
<filter>
<!-- The CORS filter with parameters -->
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<!-- Note: All parameters are options, if ommitted CORS Filter
will fall back to the respective default values.
-->
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Content-Type, X-Requested-With, x-gwt-module-base, x-gwt-permutation, origin</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>X-Test-1, X-Test-2</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Please see here for more information about the filter.
CAUTION: Further more I have tested this solution with IE 8 and unfortunately it is, as expected, NOT working with IE 8. I haven't tested it with more recent versions but since IE 8 is still in the wild I have to include the rpc-servlet into the same origin website via mod_jk.