2

I make a request to a server through the client browser like so https://example.com/bar, but get the error:

Access to XMLHttpRequest at 'https://example.com/bar/' from origin 'https://www.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

However, when using clj-http.client, I get the following headers:

{"Access-Control-Allow-Headers" "Content-Type",
  "Server" "Aleph/0.4.4",
  "Via" "1.1 vegur",
  "Content-Type" "application/edn",
  "Access-Control-Allow-Origin" "*",
  "Connection" "close",
  "Transfer-Encoding" "chunked",
  "Access-Control-Request-Method" "GET",
  "Date" "Sat, 14 Mar 2020 10:10:43 GMT",
  "Vary" "Accept-Encoding"},

If the Access-Control-Allow-Origin is present in the header through the clj-http.client request, then why does the browser say it isn't?

--- EDIT ---

What works:

;; clj-http.client gives the correct response with the headers above. 
(get "https://www.example.com/bar")

gives:

{:cached nil,
 :request-time 456,
 :repeatable? false,
 :protocol-version {:name "HTTP", :major 1, :minor 1},
 :streaming? true,
 :http-client
 #object[org.apache.http.impl.client.InternalHttpClient 0x367237a0 "org.apache.http.impl.client.InternalHttpClient@367237a0"],
 :chunked? true,
 :reason-phrase "OK",
 :headers
 {"Access-Control-Allow-Headers" "Content-Type",
  "Server" "Aleph/0.4.4",
  "Via" "1.1 vegur",
  "Content-Type" "application/edn",
  "Access-Control-Allow-Origin" "*",
  "Connection" "close",
  "Transfer-Encoding" "chunked",
  "Access-Control-Request-Method" "GET",
  "Date" "Sat, 14 Mar 2020 18:54:05 GMT",
  "Vary" "Accept-Encoding"},
 :orig-content-encoding nil,
 :status 200,
 :length -1,
 :body
 "({:foo \"bar\", :foo2 \"bar2\", :foo4 0, :foo3 [\"...
 :trace-redirects []
}

What doesn't work

;; At the client, using cljs-http.client
   (go (let [response (<! (http/get https://example.com/bar))]  
        (prn response)))

prints

{:status 0, :success false, :body "", :headers {}, :trace-redirects ["https://example.com/bar" "https://example.com/bar"], :error-code :http-error, :error-text " [0]"}
zengod
  • 1,114
  • 13
  • 26
  • What’s the HTTP status code of the response? You can use the Network pane in browser devtools to check. Is it a 4xx or 5xx error rather than a 200 OK success response? – sideshowbarker Mar 14 '20 at 10:54
  • status is 200 as expected. – zengod Mar 14 '20 at 12:07
  • we need the full request and response here – Jochen Bedersdorfer Mar 14 '20 at 17:38
  • CORS is a very tricky topic especially with Chrome. Also, if the request you are making is not a "simple request" - a preflight call will be made that needs to be handled correctly. – Jochen Bedersdorfer Mar 14 '20 at 17:41
  • also, if you are sending credentials (like a cookie or an Authorization header), you can't use 'Access-Control-Allow-Origin' set to "*". – Jochen Bedersdorfer Mar 14 '20 at 17:51
  • all the messy details are here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS – Jochen Bedersdorfer Mar 14 '20 at 17:51
  • full response in the updated edit. – zengod Mar 14 '20 at 19:01
  • @JochenBedersdorfer, the problem boils down to using clj-http client and cljs-http.client. It works when I use clj-http (even when the request server isn't the same as the response server) but doesn't when I use cljs-http. In the former case I get status 200, and in the latter status 0. – zengod Mar 15 '20 at 09:53
  • Why would the cljs-http.client request be blocked by the cors policy if the clj-http.client request isn't? – zengod Mar 15 '20 at 10:03
  • because if you are running in a browser, all actual HTTP requests are done and controlled by the browser. It doesn't matter if you are using `fetch` or `cljs-http` or `XMLHttpRequest`. The security mechanism in the browser will enforce CORS (see link above) – Jochen Bedersdorfer Mar 15 '20 at 16:17

0 Answers0