Reputation: 1179
I am setting in my custom rest endpoint the "Access-Control-Allow-Origin", but when I call this webservice from javascript, I get the following error
XMLHttpRequest cannot load http://10.239.12.22:8042/LATEST/resources/repoUIFacet?rs:q=TNF. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://gprulcd707873.abbvienet.com:8000' is therefore not allowed access. The response had HTTP status code 401.
Following is the code where I set the response header
(: Function responding to GET method - must use local name 'get':)
declare function repoUIFacet:get($context as map:map, $params as map:map) as document-node()*
{
let $output-types := map:put($context,"output-types","application/json")
let $_ := xdmp:add-response-header("Access-Control-Allow-Origin", "*")
...
};
How do I set the response header for an OPTIONS request ?
Upvotes: 1
Views: 345
Reputation: 1179
If anyone is interested, Following is what I did instead of writing a custom webservice layer in front of MarkLogic custom rest-api..
I basically have an Apache server that acts as proxy to custom Marklogic endpoints. Then I set the CORS header for it.. And also catch the OPTIONS request and send a 200.. Just letting you know, that when the request has Authorization. the '*' Access-Control-Allow-Origin *
, will not work.. you need to specify the hosts.. I did a workaround of putting a regular expression, following is how I do it in my apache config or .htaccess file
<IfModule mod_headers.c>
SetEnvIf Origin "^http(s)?://(.+\.)?(YOUR_DOMAIN.com)(:[0-9]+)?$" origin_is=$0
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "X-Requested-With, content-type, Access-Control-Allow-Origin, Authorization, X-User-Id"
</IfModule>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
ProxyPass /cr_dev http://10.239.12.22:8042/LATEST/resources
ProxyPassReverse /cr_dev/ http://10.239.12.22:8042/LATEST/resources
Upvotes: 2
Reputation: 7736
I ran into a similar issue lately. On issuing a request from the browser, the browser sends an additional OPTIONS request to MarkLogic. However my router checked for an api_key and if it didn't exists I responded with a 40x code.
What worked was respsonding with a 200 code whenever the incoming method is OPTIONS before checking the api key. All other methods check the api and return the appropriate response code.
e.g. if you are using an xquery router, you could try something like this:
let $method := fn:lower-case(xdmp:get-request-method())
(: Intercept OPTIONS method and respond immediately :)
if ($methods = 'options') then
xdmp:set-response-code(200, 'OK')
else (:
invoke the endpoint function "$method", e.g. repoUIFacet:get
:)
Good luck!
Upvotes: 2
Reputation: 20414
The error message ends with The response had HTTP status code 401
. This is an issue with authentication, not with the access control header. You need to send credentials, or switch the app server to application-level authentication.
HTH!
Upvotes: 2