如何实现 JSONP 调用

How to implement a JSONP call

先声明一下,我对 ClojureScript 还是很陌生。

我正在尝试解析已关闭 CORS 的 API。我唯一的选择是使用 JSONP 请求。但我不知道这是怎么做到的。据我了解 JSONP,returns 回调脚本是服务器。

如何在 ClojureScript 中实现它?我有我尝试使用的这个片段:

(defn get-json [url callback]
  (xhr/send url callback "GET"))

(defn logcallback [event]
  (let [response (.-target event)]
    (.log js/console (response))))

(get-json ("http://www.apiurl.com/method")
           logcallback)

但我仍然收到 Origin "localhost:3449" is not allowed (CORS) 错误。我想这并不是真正的 JSONP 请求。我该怎么做呢?

您可以使用 goog.net.Jsonp。这是一个简单的例子:

(ns jsonp.core
  (:import [goog.net Jsonp]
           [goog Uri]))

(defn success-handler [res]
  (.log js/console res))

(defn error-handler [res]
  (js/alert (str "Found an error: " res)))

(let [url "http://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=clojure"
      jsonp (goog.net.Jsonp. (Uri. url))]
  (.send jsonp nil success-handler error-handler))

如果你的端点returns一个"wrapped payload"并且设置回调名称的参数不是"callback",你可以将回调参数名称作为第二个参数传递给Jsonp构造函数.以下示例获取需要 "jsoncallback" 参数的 flickr 提要:

(let [url "http://api.flickr.com/services/feeds/photos_public.gne?format=json"
      jsonp (goog.net.Jsonp. (Uri. url) "jsoncallback")]
  (.send jsonp nil success-handler error-handler))

goog.net.Jsonp 将负责传递额外的参数(示例中的 jsoncallback)并通过调用函数解包有效负载。在任何一种情况下,它都会结束调用成功或错误处理程序。

你可以看看 clojurescript 101 by David Nolen. The post is from 2 years ago, but it should still work. There's also another clojurescript tutorial 里面有一个类似的例子。