Search code examples
javascriptjavatomcatcorsdropzone

Tomcat endpoint CORS policy responding with no "Access-Control-Allow-Origin" header


I am trying to send a post request using dropzone.js to my local Tomcat server, however, chrome is responding stating that.

Access to XMLHttpRequest at 'https://testserver.local/upload' from origin 'http://localhost:7887' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

and dropzonejs states when hovering over the upload

Server responded with 0 code.

however in my endpoint I have the following doOptions which allows the above origin.

Am i missing something in my CORS options or is this a dropzonejs issue?

    @WebServlet(value = "/upload", loadOnStartup = 0)
public class UploadEndpoint extends HttpServlet
{
    private static final long serialVersionUID = 1L;

    @Override
    protected void doOptions(HttpServletRequest req,
            HttpServletResponse resp)
            throws ServletException, IOException
    {
        resp.setHeader("Access-Control-Allow-Origin", "http://localhost:7887");
        resp.setHeader("Access-Control-Allow-Methods", "POST GET HEAD");
        resp.setHeader("Access-Control-Allow-Headers", "*");
    }

        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            if (!ServletFileUpload.isMultipartContent(request)) { throw new IllegalArgumentException("Request is not multipart, please 'multipart/form-data' enctype for your form."); }
            ServletFileUpload uploadHandler = new ServletFileUpload(new DiskFileItemFactory());
            PrintWriter writer = response.getWriter();
            try
            {
                List<FileItem> items = uploadHandler.parseRequest(new ServletRequestContext(request));
                for (FileItem item : items)
                {
                    if (!item.isFormField())
                    {
                        File file = new File(request.getServletContext().getRealPath("/") + "uploads/", item.getName());
                        item.write(file);
                    }
                }
            }
            catch (FileUploadException e)
            {
                throw new RuntimeException(e);
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                writer.close();
            }
        }
    }

Here is the webpage (fluff has been removed for simplicity), of course you will need the relevant dropzonejs JavaScript file and CSS file.

<html>
    <head>
        <script src="dropzone.js"></script>
        <link rel="stylesheet" type="text/css" href="dropzone.css">
    </head>
    <body>
        <form action="https://trainor.org.uk:19001/Music/upload" class="dropzone" id="drop_zone"></form>
    </body>
</html>

Solution

  • The OPTIONS request is used for CORS preflights if your AJAX requests contains custom headers.

    Your request isn't triggering a preflight, so it doesn't send an OPTIONS request and never sees those headers.

    You need to serve those headers in the POST response.