Hi all i have an istance of xwiki on my localhost, for a test purpose i wanted to test the RESTful api by writing some simple jquery script:
<script type="text/javascript">
var username = "Admin";
var password ="admin";
function make_base_auth(user, password)
{
var tok = user + ':' + password;
var hash = btoa(tok);
alert(hash);
return "Basic " + hash;
}
var url = "http://localhost:8080/xwiki/rest/wikis/query?q=object:XWiki.XWikiUsers";
var returnData = "";
$.ajax({
type: "GET",
dataType: "xml",
crossDomain: true,
async: true,
url: url,
headers: {"authorization": make_base_auth(username, password), "Access-Control-Allow-Origin": "*" },
error: function(request, status, error)
{
alert(error)
},
success: function(data)
{
alert("success");
}
});
</script>
the error i get is:
XMLHttpRequest cannot load http://localhost:8080/xwiki/rest/wikis/query?q=object:XWiki.XWikiUsers. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
but trying with postman i get the correct result...i'm missing something? thanks
In the default configuration XWiki does not allow CORS; you need to enable it in the web.xml
To allow sending authentication data with the authentication
header, edit the file web.xml and add a new filter among the section with the filters:
<filter>
<filter-name>Set CORS headers very lenitent</filter-name>
<filter-class>org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>Access-Control-Allow-Headers</param-value>
</init-param>
<init-param>
<param-name>value</param-name>
<param-value>authorization</param-value>
</init-param>
</filter>
Now you need to activate the filter; further down among the filter-mapping
s add your own:
<filter-mapping>
<filter-name>Set CORS headers very lenitent</filter-name>
<servlet-name>RestletServlet</servlet-name>
</filter-mapping>
(and yes, if you do not like the filter name, use a different name, just use the same name in both places.)
As you figured out in the comments, allowing several HTTP headers works like:
<filter>
<filter-name>Set CORS headers very lenitent</filter-name>
<filter-class>org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>Access-Control-Allow-Headers</param-value>
</init-param>
<init-param>
<param-name>value</param-name>
<param-value>authorization, content-type</param-value>
</init-param>
</filter>
(in this case allowing both the authorization
header and a "non-standard" Content-Type
header) (side note: headers are case-nsensitive: Are HTTP headers case-sensitive?)
Also you need to allow CORS in general for REST-request; for this search for:
<!-- We set the CORS policy globally for webjars.
... longer comment ....
-->
<filter-mapping>
<filter-name>Set CORS policy for fonts</filter-name>
<servlet-name>resourceReferenceHandler</servlet-name>
<url-pattern>/webjars/*</url-pattern>
<url-pattern>*.woff</url-pattern>
<url-pattern>*.eot</url-pattern>
<url-pattern>*.ttf</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
edit the filter-mapping and add a line <servlet-name>RestletServlet</servlet-name>
to activate this filter for the rest servlet, too:
<filter-mapping>
<filter-name>Set CORS policy for fonts</filter-name>
<servlet-name>resourceReferenceHandler</servlet-name>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/webjars/*</url-pattern>
[...]
After a restart of the servlet container the AJAX request should now work.
You can modify web.xml file for enabling cors (I am using jetty server). I added the below mentioned filter.
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<param-value>GET,POST,DELETE,PUT,HEAD</param-value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>origin, content-type, accept, authorization</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Then you need to Download and add jetty servlet jar from here
Put this jar inside the lib folder, then restart your server and the cors is enabled for jetty server.