Я создаю демонстрационное приложение в clojurescript с помощью KeeFrame, и для получения части информации для этого веб-сайта мне нужно вызвать внешний API, для которого требуется настраиваемый параметр заголовка HTTP в запросах GET.
Я использую re-frame.core для вызовов API, который использует ajax.core. Я также попытался заменить это на cljs-http.client. Однако результат тот же. Мне уже удалось добавить пользовательские параметры заголовка в заголовок запроса, используя clj-http на сайте сервера. Но это не то решение, которое я хочу реализовать для этого веб-сайта, потому что это означает, что мне сначала нужно перестроить API, который я вызываю. Поэтому я могу использовать его из своего clojurescript без параметра.
Этот код работает. Генерируется корректный GET-запрос
{:http-xhrio {
:method :get
:uri (str transuri "/acquirer/" 673072009 "/acquirerref/" acquirerRefNo)
:headers {"Accept" "application/json"}
:response-format (http/json-response-format {:keywords? true})
:on-failure [:common/set-error]}}
С «Accept: application/json» в качестве заголовка запроса
Этот код не работает. Вместо запроса GET генерируется запрос OPTIONS.
{:http-xhrio {
:method :get
:uri (str transuri "/acquirer/" 673072009 "/acquirerref/" acquirerRefNo)
:headers {"Accept" "application/json" "Custom" "Value"}
:response-format (http/json-response-format {:keywords? true})
:on-failure [:common/set-error]}}
А в заголовке запроса "Accept: application/json" не видно, а "Access-Control-Request-Headers: custom" есть
Я ожидал запрос GET с «Accept: application/json» и «Custom: Value» в заголовке запроса.
Может ли кто-нибудь сказать мне, что я делаю неправильно, или предоставить мне ссылку с информацией об этом?
заранее спасибо
Я не использовал KeeFrame, но у меня есть рабочий пример с использованием новой библиотеки re-frame
, над которой я работаю. Он вызывает запрос ajax, используя этот перехватчик:
(def ajax-intc
"Interceptor for performing AJAX requests"
(interceptor
{:id :ajax-intc
:enter identity
:leave (fn [ctx] ; #todo (with-result ctx ...)
(let [ajax (:ajax ctx)]
;(t/spyx :ajax-intc-start ctx)
;(t/spyx :ajax-intc-start ajax)
(when-not (nil? ajax)
(t/spy :awt-ajax-intc--ajax ajax)
(let [method (t/grab :method ajax)
uri (t/grab :uri ajax)
ajax-opts-present (set/intersection (set (keys ajax)) ajax-options-keys)
opts-map (t/submap-by-keys ajax ajax-opts-present)]
;(t/spy :ajax-intc-ready (t/vals->map method uri opts-map))
(condp = method
:get (do
(t/spy :awt-ajax-intc--opts-map opts-map)
(ajax/GET uri opts-map))
:put (ajax/PUT uri opts-map)
:post (ajax/POST uri opts-map)
(throw (ex-info "ajax-intc: unrecognized :method" ajax))))))
ctx)}))
При вызове с этим событием:
(flame/dispatch-event [:ajax-demo :get "/fox.txt"
{:handler ajax-handler
:error-handler ajax-error-handler
:headers {"custom" "something"}
}])
в консоли Chrome dev можно увидеть, что заголовки проходят:
:awt-localstore-load-intc--loaded-value-1 {}
core.cljs:192 :awt-ajax-intc--ajax => {:method :get, :uri "/fox.txt", :handler #object[flintstones$core$ajax_handler], :error-handler #object[flintstones$core$ajax_error_handler], :headers {"custom" "something"}}
core.cljs:192 :awt-ajax-intc--opts-map => {:handler #object[flintstones$core$ajax_handler], :error-handler #object[flintstones$core$ajax_error_handler], :headers {"custom" "something"}}
Если вы хотите попробовать, вы можете клонировать этот репозиторий: [email protected]:cloojure/cljs-enflame.git
а затем запустите:
lein clean
lein figwheel
и посмотрите, как он запускается в браузере.
Браузер отправит запрос OPTIONS «предварительной проверки», чтобы убедиться, что ему разрешено отправлять заголовок запроса «Custom». Предполагается, что сервер одобрит, ответив «Access-Control-Allow-Headers».
См. https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Это действительно произошло. Но из-за брандмауэров запрос OPTIONS не отвечает с этого сайта, и поэтому запрос GET никогда не был отправлен.