2013-04-29 92 views
2

我使用request.el庫(可通過MELPA獲得)嘗試創建基本框架,從Stack Exchange mode for Emacs開始正式開始工作。我所要做的就是能夠將由json-read解析的對象返回給調用函數,但我似乎無法建立連接。Request.el「無法創建與api.stackexchange.com的連接」

據我所知,要讓我的函數返回對象,調用必須同步進行,所以這就是:sync t。我曾考慮過把它作爲一個異步調用,但我認爲考慮它的用例並不會有好處。

起初,在看了這些信息之後,我想'也許我沒有必要的二進制文件。'我測試了request.el以及一些與它的文檔一起提供的示例調用,並且它們工作正常,所以沒有了。

我不知道什麼是錯的。我還沒有很多經驗,成功或其他方面的經驗,處理網絡的任何事情,並沒有完全理解我得到的錯誤消息。據我所知,API的443端口給了我沉默的待遇,但我很猶豫,認爲是這種情況;)

;; Works like a charm 
(defun alist-to-json (alist) 
    "Converts the key-value pairs of `ALIST` into a JSON-friendly 
string: \"key1=value1&key2=value2&\"." 
    (apply 'concat 
    (mapcar (lambda (kv) 
       (format "%s=%s&" (car kv) 
         (if (stringp (cdr kv)) 
          (cdr kv) 
         (number-to-string (cdr kv))))) 
      alist))) 


(defvar stack-api-root "https://api.stackexchange.com/2.1/") 

(require 'json) 
(require 'request) 

(defun stack-api-request (call keys-alist) 
    "Makes the specified `CALL` to the Stack Exchange API with the 
    key-value pairs given `KEYS-ALIST`. For example, 

    (stack-api-request \"sites\" '((page . 2) (page_size . 25)))" 

    (let* ((base-call (concat stack-api-root call "?")) 
     (options (alist-to-json keys-alist))) 
    (request base-call 
    :params options 
    :parser 'json-read 
    :sync t))) 

回溯

Debugger entered--Lisp error: (error "Could not create connection to api.stackexchange.com:443") 
    signal(error ("Could not create connection to api.stackexchange.com:443")) 
    error("Could not create connection to %s:%d" "api.stackexchange.com" 443) 
    url-http([cl-struct-url "https" nil nil "api.stackexchange.com" nil "/2.1/sites?&" nil nil t nil t] #[128 "\302\303\304p#\210\300\305\240\210\301p\240\207" [(nil) (nil) url-debug retrieval "Synchronous fetching done (%S)" t] 5 "\n\n(fn &rest IGNORED)"] (nil)) 
    url-https([cl-struct-url "https" nil nil "api.stackexchange.com" nil "/2.1/sites?&" nil nil t nil t] #[128 "\302\303\304p#\210\300\305\240\210\301p\240\207" [(nil) (nil) url-debug retrieval "Synchronous fetching done (%S)" t] 5 "\n\n(fn &rest IGNORED)"] (nil)) 
    url-retrieve-internal("https://api.stackexchange.com/2.1/sites?&" #[128 "\302\303\304p#\210\300\305\240\210\301p\240\207" [(nil) (nil) url-debug retrieval "Synchronous fetching done (%S)" t] 5 "\n\n(fn &rest IGNORED)"] (nil) nil nil) 
    url-retrieve("https://api.stackexchange.com/2.1/sites?&" #[128 "\302\303\304p#\210\300\305\240\210\301p\240\207" [(nil) (nil) url-debug retrieval "Synchronous fetching done (%S)" t] 5 "\n\n(fn &rest IGNORED)"]) 
    url-retrieve-synchronously("https://api.stackexchange.com/2.1/sites?&") 
    request--url-retrieve-sync("https://api.stackexchange.com/2.1/sites?&" :params "page=2&page_size=25&" :parser json-read :sync t :error (closure (t) (&rest args) (apply (quote request-default-error-callback) (quote "https://api.stackexchange.com/2.1/sites?") args)) :url "https://api.stackexchange.com/2.1/sites?&" :response [cl-struct-request-response nil nil nil nil nil "https://api.stackexchange.com/2.1/sites?&" nil (:params "page=2&page_size=25&" :parser json-read :sync t :error (closure (t) (&rest args) (apply (quote request-default-error-callback) (quote "https://api.stackexchange.com/2.1/sites?") args)) :url "https://api.stackexchange.com/2.1/sites?&" :response #0) nil nil nil url-retrieve nil]) 
    apply(request--url-retrieve-sync "https://api.stackexchange.com/2.1/sites?&" (:params "page=2&page_size=25&" :parser json-read :sync t :error (closure (t) (&rest args) (apply (quote request-default-error-callback) (quote "https://api.stackexchange.com/2.1/sites?") args)) :url "https://api.stackexchange.com/2.1/sites?&" :response [cl-struct-request-response nil nil nil nil nil "https://api.stackexchange.com/2.1/sites?&" nil #0 nil nil nil url-retrieve nil])) 
    request("https://api.stackexchange.com/2.1/sites?" :params "page=2&page_size=25&" :parser json-read :sync t) 
    (let* ((base-call (concat stack-api-root call "?")) (options (alist-to-json keys-alist))) (request base-call :params options :parser (quote json-read) :sync t)) 
    stack-api-request("sites" ((page . 2) (page_size . 25))) 
    eval((stack-api-request "sites" (quote ((page . 2) (page_size . 25)))) nil) 
    eval-expression((stack-api-request "sites" (quote ((page . 2) (page_size . 25)))) nil) 
    call-interactively(eval-expression nil nil) 

消息:

Contacting host: api.stackexchange.com:443 
Opening TLS connection to `api.stackexchange.com'... 
Opening TLS connection with `gnutls-cli --insecure -p 443 api.stackexchange.com'...failed 
Opening TLS connection with `gnutls-cli --insecure -p 443 api.stackexchange.com --protocols ssl3'...failed 
Opening TLS connection with `openssl s_client -connect api.stackexchange.com:443 -no_ssl2 -ign_eof'...failed 
Opening TLS connection to `api.stackexchange.com'...failed 

I checked,以確保這不符合捲曲問題。我用curl電話是

curl api.stackexchange.com/2.1/sites --compressed 

從外面看進request庫,request的那樣好這樣做。我不知道會發生什麼問題。

+0

我沒有時間仔細查看問題,但是您是否使用捲曲後端檢查它?也許這是另一個url.el的錯誤。如果你有捲曲(命令行一,而不是libcurl),它將被自動使用。我建議通過url.el來使用它。 – tkf 2013-04-30 21:40:04

+0

@tkf首先感謝您的閱讀。我已經忘記了我正在一臺癱瘓的計算機上(windows,沒有cygwin/admin;非常漫長而悲傷的故事),並且將研究curl業務 - 我想我可以使用Windows的獨立版本,而且我將會報告更新。 – 2013-04-30 21:42:49

+0

「REQUEST [錯誤]連接到... api .../sites時出錯(錯誤)」這是很多錯誤,但代碼是60(並且,假設它是'curl'錯誤,「對等證書不能「)鑑於我獲得了不同的結果,我認爲我做得對,我無法在Windows端口和url.el之間獲勝。 – 2013-04-30 21:58:04

回答

1

我把你的例子簡化成下面的代碼片段來重現你的問題,但它確實有效。你可以試試這個嗎?

(request 
"http://api.stackexchange.com/2.1/sites" 
:parser 'json-read 
:params '((page . "2") (page_size . "25")) 
:success (lambda (&rest args) (princ (plist-get args :data)))) 

它應該打印一些數據到*Messages*緩衝區和回波區域。

編輯:你的例子中的問題似乎是你要傳遞字符串到PARAMS只需要alist。我將更改代碼以引發錯誤,以便更易於調試。

+0

從[文檔](http://tkf.github.io/emacs-request/)中的POST示例中,字符串應該是等效的,否? – 2013-05-05 10:59:46

+0

DATA允許字符串,但不允許PARAMS。 PARAMS去url和DATA模仿HTML表單等等。但是PARAMS應該接受字符串。 – tkf 2013-05-05 13:54:32

+0

啊,我現在明白了。那裏有兩個不同的論點感謝您的支持! – 2013-05-05 17:12:59