OPTION requests to the REST api returning 404

Infos:

  • Used Zammad version: 2.2.x
  • Used Zammad installation source: zammad.com is hosting it
  • Operating system: I’m using Fedora Linux
  • Browser + version: Chrome 62.0.3202.94

Expected behavior:

As described here an OPTIONS request to a server is supposed to return information about how the server’s REST api can be used.

Actual behavior:

Its returning a 404 page (side note: the 404 page is a little broken, It’s returning a bunch of what looks like asp. At least for the specific subdomain I’m under as can be seen here)

Steps to reproduce the behavior:

curl -X OPTIONS https://wpoverwatch.zammad.com/api/v1/ticket_priorities -i

Reason this matters

I’ve been having troubles using the REST api and I’ve narrowed down the problem to this. I don’t know much about CORS policies, but I kept getting CORS errors along with 404 errors whenever I tried to use the Zammad REST api from my browser. I eventually figured out that the 404 errors were a result of the browser doing a “preflight” check first to see if your servers support CORS. It seems it does this by doing an OPTIONS request. Your servers are returning 404 pages as a result of the OPTIONS request, and the browser seems to interpret this as the server not supporting CORS and thus the browser doesn’t send the actual request I was trying to send. Other utilities like python or postman have been able to do requests to the server just find and use the REST api, I’m guessing because they work with CORS a little different or are a little more lenient with it. Either way I’m unable to use the REST api from the webpage I’m trying to make because of this.

By the way, it seems I’m not the only one running into this problem. Here’s a stackoverflow question I found of someone else trying to do exactly the same thing with your REST api.

Right now this is “works as designed” because we did not implement the OPTIONS method in Zammad. There is no relation to CORS or something else, we simply don’t offer this method.
If you are having troubles regarding special REST requests feel free to drop a question. Maybe we can extend our documentation based on this.

regards

Johannes

Alright, well this is specifically the command I’m trying to do.

fetch('https://wpoverwatch.zammad.com/api/v1/ticket_priorities', {
  method: 'GET',
  headers: new Headers({
    Authorization: 'Token token=<MY TOKEN>'
  })
})

And this is what is happening.


Is there a different or better way to send this request to the server’s REST api? What command would you put in the console to make it work?

So… how would you guys recommend calling into the REST api with javascript? Do you think you could show me any example code that works, or guide me in what I should do?

Thanks.

Hi Scott,

you try to get the priorities from Zammad. There are two ways:

  1. directly
## Get priorities
curl "https://YOURZAMMAD/api/v1/ticket_priorities" \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -H 'Authorization : Token token=XXX' \
     -d $'{}'
  1. You make a call to signshow
## Check Login Duplicate
curl -X "POST" "https://YOURZAMMAD/api/v1/signshow" \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -H 'Authorization : Token token=XXX'

In return you get:

regards

Thanks for the help! I got the first command to work after removing the space between Header and ‘:’, and removing the -d '${}'. The second command wasn’t returning the assets section of the json, and additionally it returned in the json the following key/value pair. “error”:“no valid session”, but maybe if I played with it more I could get that command working also.

But my problem here is that I would like to do it from my javascript app. I’ve also been able to successfully get the ticket priorities via postman and python, but not javascript. Postman is even able to auto-generate javascript code that’s supposed to be able to work, but that auto-generated code receives the same CORS errors. I believe the reason why its not working in javascript is due to a CORS issue, but like I said, I don’t know very much about CORS.

If I have to, or if what I’m trying to do isn’t really possible, I could always make a REST api for my javascript app that simply forwards the rest calls to your system, where the rest api makes its requests using python or curl or something, but that just seems redundant.

So what is the right way to use your REST api with Javascript?

Thanks.

I’m sorry but I can’t help you with a specific language in this case. We “only” support Zammad and Zammad’s web app uses the API as a basic feature for everything. I don’t know anything about your setup or restrictions in your environment. Which is responsible for the CORS handling. Zammad has no preference / settings there.

regards
Johannes

I’m going to post a little info here on more stuff I have found about CORS. However, I understand that you said you won’t fix this, and I’m totally fine with that. I’ll just make an intermediate server to allow myself to communicate with your REST api.

Anyways, here’s the additional info I found on MDN.

What requests use CORS?
This cross-origin sharing standard is used to enable cross-site HTTP requests for:
• Invocations of the XMLHttpRequest or Fetch APIs in a cross-site manner, …
• …

the XMLHttpRequest and the Fetch APIs are the only ways for javascript to communicate with external servers, so by not supporting CORS no other javascript application can use your REST api directly, only indirectly through other non-javascript servers.

Some snippets from this MDN article explains further what the CORS preflight check is.

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood.
It is an OPTIONS request …
A preflight request is automatically issued by a browser when needed; …

For example, a client might be asking a server if it would allow a DELETE request, before actually sending a DELETE request by using a preflight request: …
If the server allows it, then it will respond to the preflight request with a Access-Control-Allow-Methods response header response header that lists DELETE:

Which by the way, your server actually does return the correct Access-Control-Allow-Methods headers. Specifically your server gives me the following header:
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, PATCH, OPTIONS
Its explained here that this header is specifically used in response to preflight (OPTIONS) requests to tell the client which request methods the server accepts. In other words, this header isn’t doing anything right now because preflight checks aren’t supported. (funny enough, this header is stating that the OPTIONS request is supported, even though it’s not).

The fact that the server is returning anything with Access-Control-Allow-* shows that an attempt was made to make the server work properly with CORS, as those headers are only used with CORS policies to my understanding.

By the way, while working on an intermediate server to communicate with yours, I found out that implementing the OPTIONS request in php is really as simple as die(). Any other language should be just as simple. As long as it returns the correct headers (which your server already seems to be doing), and the status code indicates no errors, then its implemented!

You mentioned that the Zammad web app works with the api just fine, and that would be expected, because its on the same domain as the api. CORS doesn’t apply when both resources are on the same domain.

So this really isn’t anything too specific to my setup or environment. In my first post I mentioned someone else on stackoverflow who was having the same problem with your REST api, and as far as I can tell, anyone who uses javascript would be unable to access your rest api directly, only indirectly through other servers.

However, if it is of value, my exact environment was shown above. I’m using Chrome 62.0.3202.94 and I pasted that javascript command into the browser and received a CORS error as shown in the screenshot. There’s nothing more to it, anyone should be able to get the same error by using the same javascript command in the browser.

Anyways, like I said, I’m totally cool with making another server to access your REST api, and in fact am already working on it, I just wanted to put this info out there. Also, as an unrelated side note, you still might want to look into why this 404 page is returning asp looking stuff.

Thanks for your help.

Additionally, above you mentioned extending your documentation to help prevent confusion. If you really don’t plan on making the OPTIONS request work, then a browser can’t do a preflight check (because that’s only done using an OPTIONS request), therefore CORS won’t be correctly implemented with your server, because part of CORS is the ability for preflight checks to work. Maybe it would be of worth to other people to mention in your documentation that the REST api can’t be accessed with javascript because CORS is not fully supported.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.