9

我正在尝试从 Emacs 的 elisp 访问 StackExchange API:

(require 'url)
(require 'json)

(defvar url-http-end-of-headers)

(defun read-json ()
  (interactive)
  (with-current-buffer (url-retrieve-synchronously "http://api.stackoverflow.com/0.8/users/2386")
  (goto-char url-http-end-of-headers)
  (json-read)))

M-x read-json导致以下错误:JSON readtable error

我错过了什么吗?

4

1 回答 1

11

这几乎肯定与 gzip 编码有关,原始服务器响应如下:

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 10 Jun 2010 03:41:20 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: private
Content-Encoding: gzip
X-AspNetMvc-Version: 2.0
X-RateLimit-Max: 300
X-RateLimit-Current: 290
X-AspNet-Version: 2.0.50727
Content-Length: 676

{compressed  body}

客户端似乎没有明确表示它支持 gzip(请注意缺少 Accept-Encoding 标头),但服务器无论如何都会压缩响应。以下是运行您的代码时来自我的客户的请求标头:

GET /0.8/users/2386 HTTP/1.1
MIME-Version: 1.0
Connection: keep-alive
Extension: Security/Digest Security/SSL
Host: api.stackoverflow.com
Accept-charset: iso-8859-1;q=1, gb2312;q=0.5, utf-8;q=0.5, big5;q=0.5, iso-2022-jp;q=0.5, shift_jis;q=0.5, euc-tw;q=0.5, euc-jp;q=0.5, euc-jis-2004;q=0.5, euc-kr;q=0.5, us-ascii;q=0.5, utf-7;q=0.5, hz-gb-2312;q=0.5, big5-hkscs;q=0.5, gbk;q=0.5, gb18030;q=0.5, iso-8859-5;q=0.5, koi8-r;q=0.5, koi8-u;q=0.5, cp866;q=0.5, koi8-t;q=0.5, windows-1251;q=0.5, cp855;q=0.5, iso-8859-2;q=0.5, iso-8859-3;q=0.5, iso-8859-4;q=0.5, iso-8859-9;q=0.5, iso-8859-10;q=0.5, iso-8859-13;q=0.5, iso-8859-14;q=0.5, iso-8859-15;q=0.5, windows-1250;q=0.5, windows-1252;q=0.5, windows-1254;q=0.5, windows-1257;q=0.5, cp850;q=0.5, cp852;q=0.5, cp857;q=0.5, cp858;q=0.5, cp860;q=0.5, cp861;q=0.5, cp863;q=0.5, cp865;q=0.5, cp437;q=0.5, next;q=0.5, hp-roman8;q=0.5, adobe-standard-encoding;q=0.5, iso-8859-16;q=0.5, iso-8859-7;q=0.5, windows-1253;q=0.5, cp737;q=0.5, cp851;q=0.5, cp869;q=0.5, iso-8859-8;q=0.5, windows-1255;q=0.5, cp862;q=0.5, iso-2022-jp-2004;q=0.5, cp874;q=0.5, iso-8859-11;q=0.5, viscii;q=0.5, windows-1258;q=0.5, iso-8859-6;q=0.5, windows-1256;q=0.5, iso-2022-cn;q=0.5, iso-2022-cn-ext;q=0.5, iso-2022-jp-2;q=0.5, iso-2022-kr;q=0.5, utf-16le;q=0.5, utf-16be;q=0.5, utf-16;q=0.5, x-ctext;q=0.5
Accept: */*
User-Agent: URL/Emacs (i386-mingw-nt6.1.7600; Windows-NT; 32bit)

根据 HTTP 规范,服务器行为是可以接受的:

如果请求中没有 Accept-Encoding 字段,服务器可以假设客户端将接受任何内容编码。在这种情况下,如果“身份”是可用的内容编码之一,那么服务器应该使用“身份”内容编码,除非它有额外的信息表明不同的内容编码对客户端有意义。

如果您显式设置标头值,则会按预期返回响应:

(setq url-mime-encoding-string "identity")
于 2010-06-10T03:51:13.883 回答