Gehen Sie nach dem URL-Abrufen synchron zum Körper

7

Ich verwende url-retrieve-synchronously, um eine JSON-Datei von einem Remote-Server herunterzuladen. Diese Funktion gibt einen Puffer zurück, der den gesamten Inhalt der Antwort einschließlich der HTTP-Header enthält. Ich interessiere mich jedoch nur für den Körper.

Wie kann ich, ohne eine HTTP-Antwort manuell zu analysieren, zum Anfang des Körpers springen? Ich habe die Variable gefunden url-http-end-of-headers, die funktioniert, aber sie ist überhaupt nicht dokumentiert, und ihre Verwendung fühlt sich "schmutzig" an. Gibt es eine geeignete API für diesen Zweck?


quelle

Antworten:

3

In Bezug auf eine "richtige API" denke ich, dass die kurze Antwort derzeit "Nein" lautet - es sei denn, Sie sind bereit, sich auf eine externe Bibliothek zu verlassen. url-http-end-of-headersscheint so gut wie möglich zu sein, obwohl es weder im URL-Programmierhandbuch erwähnt noch in der Emacs-Quelle dokumentiert zu sein scheint .

dat
quelle
8

Da nach den HTTP-Headern eine neue Zeile steht, ist die einzige mir bekannte Alternative die Verwendung von re-search-forward:

(with-current-buffer
    (url-retrieve-synchronously my-url)
  (goto-char (point-min))
  (re-search-forward "^$")
  (delete-region (point) (point-min))
  (buffer-string))
mutbuerger
quelle
Nun, das ist für mich "Parsen von HTTP", und ich denke, url-http-end-of-headersist diesem Ansatz vorzuziehen. Ich hatte wirklich auf so etwas gehofft url-http-goto-body:(
3

Eine übergeordnete Alternative zur Verwendung url-http-end-of-headers, die jedoch nicht dokumentiert ist, ist url-insert-file-contents:

(with-temp-buffer
  (url-insert-file-contents
   "https://api.stackexchange.com/2.2/questions/12464?site=emacs")
  (json-parse-buffer :object-type 'alist))

oder gleichwertig vor Emacs 27, kompiliert mit nativer JSON-Unterstützung:

(require 'json)
(with-temp-buffer
  (url-insert-file-contents
   "https://api.stackexchange.com/2.2/questions/12464?site=emacs")
  (let ((json-false :false))
    (json-read)))

Diese führen zu:

((items .
  [((tags .
     ["url" "http"])
    (owner
     (reputation . 10741)
     (user_id . 227)
     (user_type . "registered")
     (accept_rate . 89)
     (profile_image . "https://i.stack.imgur.com/ebO5J.jpg?s=128&g=1")
     (display_name . "lunaryorn")
     (link . "https://emacs.stackexchange.com/users/227/lunaryorn"))
    (is_answered . t)
    (view_count . 867)
    (accepted_answer_id . 29798)
    (answer_count . 3)
    (score . 4)
    (last_activity_date . 1517363132)
    (creation_date . 1431861037)
    (question_id . 12464)
    (link . "/emacs/12464/go-to-body-after-url-retrieve-synchronously")
    (title . "Go to body after url-retrieve-synchronously"))])
 (has_more . :false)
 (quota_max . 300)
 (quota_remaining . 276))

Die Funktion url-insert-file-contentsumschließt die besser dokumentierten Funktionen url-insert-buffer-contentsund url-insertbietet daher die folgenden Extras:

  1. Standardmäßig automatisch geladen.
  2. Existiert seit mindestens Emacs 21.
  3. Einfache Behandlung von HTTP-Antwortfehlern über url-http-response-status.
  4. Dekodiert Daten.

FWIW, es kommt auch mit der Garantie, von verwendet zu werden lisp/emacs-lisp/package.el.

Basilikum
quelle