标签归档:content-type

如何在Python 2中发送HEAD HTTP请求?

问题:如何在Python 2中发送HEAD HTTP请求?

我在这里尝试做的是获取给定URL的标头,以便确定MIME类型。我希望能够查看是否http://somedomain/foo/将返回例如HTML文档或JPEG图像。因此,我需要弄清楚如何发送HEAD请求,以便无需下载内容就可以读取MIME类型。有人知道这样做的简单方法吗?

What I’m trying to do here is get the headers of a given URL so I can determine the MIME type. I want to be able to see if http://somedomain/foo/ will return an HTML document or a JPEG image for example. Thus, I need to figure out how to send a HEAD request so that I can read the MIME type without having to download the content. Does anyone know of an easy way of doing this?


回答 0

编辑:此答案有效,但是现在您应该使用下面其他答案中提到的请求库。


使用httplib

>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]

还有一个getheader(name)获取特定的标头。

edit: This answer works, but nowadays you should just use the requests library as mentioned by other answers below.


Use httplib.

>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]

There’s also a getheader(name) to get a specific header.


回答 1

urllib2可用于执行HEAD请求。这比使用httplib更好,因为urllib2为您解析URL,而不是要求您将URL分为主机名和路径。

>>> import urllib2
>>> class HeadRequest(urllib2.Request):
...     def get_method(self):
...         return "HEAD"
... 
>>> response = urllib2.urlopen(HeadRequest("http://google.com/index.html"))

头可以通过response.info()像以前一样使用。有趣的是,您可以找到重定向到的URL:

>>> print response.geturl()
http://www.google.com.au/index.html

urllib2 can be used to perform a HEAD request. This is a little nicer than using httplib since urllib2 parses the URL for you instead of requiring you to split the URL into host name and path.

>>> import urllib2
>>> class HeadRequest(urllib2.Request):
...     def get_method(self):
...         return "HEAD"
... 
>>> response = urllib2.urlopen(HeadRequest("http://google.com/index.html"))

Headers are available via response.info() as before. Interestingly, you can find the URL that you were redirected to:

>>> print response.geturl()
http://www.google.com.au/index.html

回答 2

强制Requests方式:

import requests

resp = requests.head("http://www.google.com")
print resp.status_code, resp.text, resp.headers

Obligatory Requests way:

import requests

resp = requests.head("http://www.google.com")
print resp.status_code, resp.text, resp.headers

回答 3

我认为也应该提及Requests库。

I believe the Requests library should be mentioned as well.


回答 4

只是:

import urllib2
request = urllib2.Request('http://localhost:8080')
request.get_method = lambda : 'HEAD'

response = urllib2.urlopen(request)
response.info().gettype()

编辑:我刚开始意识到有httplib2:D

import httplib2
h = httplib2.Http()
resp = h.request("http://www.google.com", 'HEAD')
assert resp[0]['status'] == 200
assert resp[0]['content-type'] == 'text/html'
...

连结文字

Just:

import urllib2
request = urllib2.Request('http://localhost:8080')
request.get_method = lambda : 'HEAD'

response = urllib2.urlopen(request)
response.info().gettype()

Edit: I’ve just came to realize there is httplib2 :D

import httplib2
h = httplib2.Http()
resp = h.request("http://www.google.com", 'HEAD')
assert resp[0]['status'] == 200
assert resp[0]['content-type'] == 'text/html'
...

link text


回答 5

为了完整起见,有一个与使用httplib接受的答案等效的Python3答案。

基本相同的代码只是该库不再被称为httplib而是http.client

from http.client import HTTPConnection

conn = HTTPConnection('www.google.com')
conn.request('HEAD', '/index.html')
res = conn.getresponse()

print(res.status, res.reason)

For completeness to have a Python3 answer equivalent to the accepted answer using httplib.

It is basically the same code just that the library isn’t called httplib anymore but http.client

from http.client import HTTPConnection

conn = HTTPConnection('www.google.com')
conn.request('HEAD', '/index.html')
res = conn.getresponse()

print(res.status, res.reason)

回答 6

import httplib
import urlparse

def unshorten_url(url):
    parsed = urlparse.urlparse(url)
    h = httplib.HTTPConnection(parsed.netloc)
    h.request('HEAD', parsed.path)
    response = h.getresponse()
    if response.status/100 == 3 and response.getheader('Location'):
        return response.getheader('Location')
    else:
        return url
import httplib
import urlparse

def unshorten_url(url):
    parsed = urlparse.urlparse(url)
    h = httplib.HTTPConnection(parsed.netloc)
    h.request('HEAD', parsed.path)
    response = h.getresponse()
    if response.status/100 == 3 and response.getheader('Location'):
        return response.getheader('Location')
    else:
        return url

回答 7

顺便说一句,当使用httplib时(至少在2.5.2上),尝试读取HEAD请求的响应将阻塞(在读取行中),随后失败。如果您未在响应中发出已读消息,则无法在连接上发送另一个请求,则需要打开一个新请求。或者接受两次请求之间的长时间延迟。

As an aside, when using the httplib (at least on 2.5.2), trying to read the response of a HEAD request will block (on readline) and subsequently fail. If you do not issue read on the response, you are unable to send another request on the connection, you will need to open a new one. Or accept a long delay between requests.


回答 8

我发现httplib比urllib2快一点。我为两个程序计时-一个使用httplib,另一个使用urllib2-将HEAD请求发送到10,000个URL。httplib的速度快了几分钟。 httplib的总统计为:实际6m21.334s用户0m2.124s sys 0m16.372s

的urllib2的总的统计是:实9m1.380s用户0m16.666s SYS 0m28.565s

有人对此有意见吗?

I have found that httplib is slightly faster than urllib2. I timed two programs – one using httplib and the other using urllib2 – sending HEAD requests to 10,000 URL’s. The httplib one was faster by several minutes. httplib‘s total stats were: real 6m21.334s user 0m2.124s sys 0m16.372s

And urllib2‘s total stats were: real 9m1.380s user 0m16.666s sys 0m28.565s

Does anybody else have input on this?


回答 9

还有另一种方法(类似于Pawel的答案):

import urllib2
import types

request = urllib2.Request('http://localhost:8080')
request.get_method = types.MethodType(lambda self: 'HEAD', request, request.__class__)

只是为了避免在实例级别使用无限制的方法。

And yet another approach (similar to Pawel answer):

import urllib2
import types

request = urllib2.Request('http://localhost:8080')
request.get_method = types.MethodType(lambda self: 'HEAD', request, request.__class__)

Just to avoid having unbounded methods at instance level.


回答 10

可能更容易:使用urllib或urllib2。

>>> import urllib
>>> f = urllib.urlopen('http://google.com')
>>> f.info().gettype()
'text/html'

f.info()是类似字典的对象,因此您可以执行f.info()[‘content-type’]等。

http://docs.python.org/library/urllib.html
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/httplib.html

文档指出,通常不直接使用httplib。

Probably easier: use urllib or urllib2.

>>> import urllib
>>> f = urllib.urlopen('http://google.com')
>>> f.info().gettype()
'text/html'

f.info() is a dictionary-like object, so you can do f.info()[‘content-type’], etc.

http://docs.python.org/library/urllib.html
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/httplib.html

The docs note that httplib is not normally used directly.


ContentType和MimeType有什么区别

问题:ContentType和MimeType有什么区别

据我所知,它们是绝对平等的。但是,浏览一些django文档,我发现了这段代码:

HttpResponse.__init__(content='', mimetype=None, status=200, content_type='text/html')

令我惊讶的是两个人相处得很好。官方文档能够以实用的方式解决此问题:

content_type是mimetype的别名。从历史上讲,此参数仅称为mimetype,但是由于它实际上是HTTP Content-Type标头中包含的值,因此它还可以包含字符集编码,这使其不仅限于MIME类型规范。如果指定了mimetype(不是None),则使用该值。否则,将使用content_type。如果两者都不给出,则使用DEFAULT_CONTENT_TYPE设置。

但是,我认为它不够清楚。为什么我们为(几乎相同的)事物使用2种不同的命名?“ Content-Type”只是浏览器请求中使用的名称,而在其外部很少使用吗?

两者之间的主要区别是什么,什么时候可以打电话给对方mimetype而不是content-type?我是卑鄙的语法纳粹吗?

As far as I know, they are absolute equal. However, browsing some django docs, I’ve found this piece of code:

HttpResponse.__init__(content='', mimetype=None, status=200, content_type='text/html')

which surprise me the two getting along each other. The official docs was able to solve the issue in a pratical manner:

content_type is an alias for mimetype. Historically, this parameter was only called mimetype, but since this is actually the value included in the HTTP Content-Type header, it can also include the character set encoding, which makes it more than just a MIME type specification. If mimetype is specified (not None), that value is used. Otherwise, content_type is used. If neither is given, the DEFAULT_CONTENT_TYPE setting is used.

However, I don’t find it elucidating enough. Why we use 2 different naming for (almost the same) thing? Is “Content-Type” just a name used in browser requests, and with very little use outside it?

What’s the main difference between the each one, and when is right to call something mimetype as opposed to content-type ? Am I being pitty and grammar nazi?


回答 0

为什么我们为(几乎相同的)事物使用2种不同的命名?“ Content-Type”只是浏览器请求中使用的名称,而在其外部很少使用吗?

两者之间的主要区别是什么,何时称呼某种mimetype而不是content-type才是正确的?我是可怜的纳粹语法吗?

原因不仅是向后兼容,而且恐怕通常出色的Django文档对此有些不易理解。MIME(至少值得阅读Wikipedia条目确实很值得)起源于扩展Internet邮件,尤其是SMTP。从那里开始,MIME和受MIME启发的扩展设计已经在许多其他协议(例如此处的HTTP)中找到了应用,当需要在现有协议中传输新型元数据或数据时,它仍在使用。有数十个RFC讨论了用于多种目的的MIME。

具体来说,Content-Type:是几个MIME标头之一。“ Mimetype”确实确实过时了,但是对MIME本身的引用却不是。如果可以的话,将该部分称为后向兼容性。

[BTW,这纯粹是一个术语问题,与语法无关。提出“语法”下的每个用法问题都是我的宠儿。咕rr

Why we use 2 different naming for (almost the same) thing? Is “Content-Type” just a name used in browser requests, and with very little use outside it?

What’s the main difference between the each one, and when is right to call something mimetype as opposed to content-type ? Am i being pitty and grammar nazi?

The reason isn’t only backward compatibility, and I’m afraid the usually excellent Django documentation is a bit hand-wavy about it. MIME (it’s really worth reading at least the Wikipedia entry) has its origin in extending internet mail, and specifically SMTP. From there, the MIME and MIME-inspired extension design has found its way into a lot of other protocols (such as HTTP here), and is still being used when new kinds of metadata or data need to be transmitted in an existing protocol. There are dozens of RFCs that discuss MIME used for a plethora of purposes.

Specifically, Content-Type: is one among several MIME headers. “Mimetype” does indeed sound obsolete, but a reference to MIME itself isn’t. Call that part backward-compatibility, if you will.

[BTW, this is purely a terminology problem which has nothing whatsoever to do with grammar. Filing every usage question under “grammar” is a pet peeve of mine. Grrrr.]


回答 1

我一直将contentType视为mimeType的超集。唯一的区别是可选字符集编码。如果contentType不包含可选字符集编码,则它与mimeType相同。否则,mimeType是字符集编码序列之前的数据。

例如 text/html; charset=UTF-8

text/html是mimeType
;是附加参数指示符
charset=UTF-8是字符集编码参数

例如 application/msword

application/msword是mimeType,
它不能具有字符集编码,因为它描述的格式octet-stream不直接包含字符。

I’ve always viewed contentType to be a superset of mimeType. The only difference being the optional character set encoding. If the contentType does not include an optional character set encoding then it is identical to a mimeType. Otherwise, the mimeType is the data prior to the character set encoding sequence.

E.G. text/html; charset=UTF-8

text/html is the mimeType
; is the additional parameters indicator
charset=UTF-8 is the character set encoding parameter

E.G. application/msword

application/msword is the mimeType
It cannot have a character set encoding as it describes a well formed octet-stream not comprising characters directly.


回答 2

如果您想了解详细信息,请参阅票证3526

引用:

向HttpResponse构造函数添加了content_type作为mimetype的别名。这是一个稍微准确的名称。基于Simon Willison的补丁。完全向后兼容。

If you want to know the details see ticket 3526.

Quote:

Added content_type as an alias for mimetype to the HttpResponse constructor. It’s a slightly more accurate name. Based on a patch from Simon Willison. Fully backwards compatible.


回答 3

为什么我们为(几乎相同的)事物使用2种不同的命名?

向后兼容性,基于您在文档中的报价。

Why we use 2 different naming for (almost the same) thing?

Backwards compatibility, based on your quote from the documentation.


传入的Django请求中的JSON数据在哪里?

问题:传入的Django请求中的JSON数据在哪里?

我正在尝试使用Django / Python处理传入的JSON / Ajax请求。

request.is_ajax()True在请求中,但是我不知道有效负载在哪里以及JSON数据。

request.POST.dir 包含以下内容:

['__class__', '__cmp__', '__contains__', '__copy__', '__deepcopy__', '__delattr__',
 '__delitem__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__setitem__', '__str__', '__weakref__', '_assert_mutable', '_encoding', 
'_get_encoding', '_mutable', '_set_encoding', 'appendlist', 'clear', 'copy', 'encoding', 
'fromkeys', 'get', 'getlist', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 
'keys', 'lists', 'pop', 'popitem', 'setdefault', 'setlist', 'setlistdefault', 'update', 
'urlencode', 'values']

在请求发布键中显然没有键。

当我查看Firebug中的POST时,请求中发送了JSON数据。

I’m trying to process incoming JSON/Ajax requests with Django/Python.

request.is_ajax() is True on the request, but I have no idea where the payload is with the JSON data.

request.POST.dir contains this:

['__class__', '__cmp__', '__contains__', '__copy__', '__deepcopy__', '__delattr__',
 '__delitem__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__setitem__', '__str__', '__weakref__', '_assert_mutable', '_encoding', 
'_get_encoding', '_mutable', '_set_encoding', 'appendlist', 'clear', 'copy', 'encoding', 
'fromkeys', 'get', 'getlist', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 
'keys', 'lists', 'pop', 'popitem', 'setdefault', 'setlist', 'setlistdefault', 'update', 
'urlencode', 'values']

There are apparently no keys in the request post keys.

When I look at the POST in Firebug, there is JSON data being sent up in the request.


回答 0

如果您要将JSON发布到Django,我想您想要request.bodyrequest.raw_post_data在Django <1.4上)。这将为您提供通过帖子发送的原始JSON数据。从那里您可以进一步处理它。

这是一个使用JavaScript,jQuery,jquery-json和Django 的示例。

JavaScript:

var myEvent = {id: calEvent.id, start: calEvent.start, end: calEvent.end,
               allDay: calEvent.allDay };
$.ajax({
    url: '/event/save-json/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: $.toJSON(myEvent),
    dataType: 'text',
    success: function(result) {
        alert(result.Result);
    }
});

Django:

def save_events_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.body   
    return HttpResponse("OK")

Django <1.4:

  def save_events_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.raw_post_data
    return HttpResponse("OK")

If you are posting JSON to Django, I think you want request.body (request.raw_post_data on Django < 1.4). This will give you the raw JSON data sent via the post. From there you can process it further.

Here is an example using JavaScript, jQuery, jquery-json and Django.

JavaScript:

var myEvent = {id: calEvent.id, start: calEvent.start, end: calEvent.end,
               allDay: calEvent.allDay };
$.ajax({
    url: '/event/save-json/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: $.toJSON(myEvent),
    dataType: 'text',
    success: function(result) {
        alert(result.Result);
    }
});

Django:

def save_events_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.body   
    return HttpResponse("OK")

Django < 1.4:

  def save_events_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.raw_post_data
    return HttpResponse("OK")

回答 1

我有同样的问题。我一直在发布复杂的JSON响应,但无法使用request.POST字典读取数据。

我的JSON POST数据为:

//JavaScript code:
//Requires json2.js and jQuery.
var response = {data:[{"a":1, "b":2},{"a":2, "b":2}]}
json_response = JSON.stringify(response); // proper serialization method, read 
                                          // http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
$.post('url',json_response);

在这种情况下,您需要使用金黄色葡萄球菌提供的方法。阅读request.body并使用json stdlib反序列化。

#Django code:
import json
def save_data(request):
  if request.method == 'POST':
    json_data = json.loads(request.body) # request.raw_post_data w/ Django < 1.4
    try:
      data = json_data['data']
    except KeyError:
      HttpResponseServerError("Malformed data!")
    HttpResponse("Got json data")

I had the same problem. I had been posting a complex JSON response, and I couldn’t read my data using the request.POST dictionary.

My JSON POST data was:

//JavaScript code:
//Requires json2.js and jQuery.
var response = {data:[{"a":1, "b":2},{"a":2, "b":2}]}
json_response = JSON.stringify(response); // proper serialization method, read 
                                          // http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
$.post('url',json_response);

In this case you need to use method provided by aurealus. Read the request.body and deserialize it with the json stdlib.

#Django code:
import json
def save_data(request):
  if request.method == 'POST':
    json_data = json.loads(request.body) # request.raw_post_data w/ Django < 1.4
    try:
      data = json_data['data']
    except KeyError:
      HttpResponseServerError("Malformed data!")
    HttpResponse("Got json data")

回答 2

方法一

客户:发送为 JSON

$.ajax({
    url: 'example.com/ajax/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    processData: false,
    data: JSON.stringify({'name':'John', 'age': 42}),
    ...
});

//Sent as a JSON object {'name':'John', 'age': 42}

服务器:

data = json.loads(request.body) # {'name':'John', 'age': 42}

方法二

客户端:发送为x-www-form-urlencoded
(注意:contentTypeprocessData已更改,JSON.stringify不需要)

$.ajax({
    url: 'example.com/ajax/',
    type: 'POST',    
    data: {'name':'John', 'age': 42},
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',  //Default
    processData: true,       
});

//Sent as a query string name=John&age=42

服务器:

data = request.POST # will be <QueryDict: {u'name':u'John', u'age': 42}>

在1.5+版本中进行了更改:https : //docs.djangoproject.com/en/dev/releases/1.5/#non-form-data-in-http-requests

HTTP请求中的非格式数据
request.POST将不再包含通过HTTP请求发布的数据,该数据头中包含非特定于格式的内容类型。在以前的版本中,以multipart / form-data或application / x-www-form-urlencoded以外的内容类型发布的数据仍将最终在request.POST属性中表示。对于这些情况,希望访问原始POST数据的开发人员应改用request.body属性。

可能相关

Method 1

Client : Send as JSON

$.ajax({
    url: 'example.com/ajax/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    processData: false,
    data: JSON.stringify({'name':'John', 'age': 42}),
    ...
});

//Sent as a JSON object {'name':'John', 'age': 42}

Server :

data = json.loads(request.body) # {'name':'John', 'age': 42}

Method 2

Client : Send as x-www-form-urlencoded
(Note: contentType & processData have changed, JSON.stringify is not needed)

$.ajax({
    url: 'example.com/ajax/',
    type: 'POST',    
    data: {'name':'John', 'age': 42},
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',  //Default
    processData: true,       
});

//Sent as a query string name=John&age=42

Server :

data = request.POST # will be <QueryDict: {u'name':u'John', u'age': 42}>

Changed in 1.5+ : https://docs.djangoproject.com/en/dev/releases/1.5/#non-form-data-in-http-requests

Non-form data in HTTP requests :
request.POST will no longer include data posted via HTTP requests with non form-specific content-types in the header. In prior versions, data posted with content-types other than multipart/form-data or application/x-www-form-urlencoded would still end up represented in the request.POST attribute. Developers wishing to access the raw POST data for these cases, should use the request.body attribute instead.

Probably related


回答 3

重要的是要记住,Python 3以不同的方式表示字符串-它们是字节数组。

使用Django 1.9和Python 2.7并在主体(而非标头)中发送JSON数据,您将使用类似以下内容:

mydata = json.loads(request.body)

但是对于Django 1.9和Python 3.4,您可以使用:

mydata = json.loads(request.body.decode("utf-8"))

我刚刚经历了这个学习过程,制作了我的第一个Py3 Django应用!

Its important to remember Python 3 has a different way to represent strings – they are byte arrays.

Using Django 1.9 and Python 2.7 and sending the JSON data in the main body (not a header) you would use something like:

mydata = json.loads(request.body)

But for Django 1.9 and Python 3.4 you would use:

mydata = json.loads(request.body.decode("utf-8"))

I just went through this learning curve making my first Py3 Django app!


回答 4

request.raw_response现在已弃用。request.body而是使用它来处理非常规表单数据,例如XML有效负载,二进制图像等。

有关此问题的Django文档

request.raw_response is now deprecated. Use request.body instead to process non-conventional form data such as XML payloads, binary images, etc.

Django documentation on the issue.


回答 5

在Django 1.6 python 3.3上

客户

$.ajax({
    url: '/urll/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(json_object),
    dataType: 'json',
    success: function(result) {
        alert(result.Result);
    }
});

服务器

def urll(request):

if request.is_ajax():
    if request.method == 'POST':
        print ('Raw Data:', request.body) 

        print ('type(request.body):', type(request.body)) # this type is bytes

        print(json.loads(request.body.decode("utf-8")))

on django 1.6 python 3.3

client

$.ajax({
    url: '/urll/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(json_object),
    dataType: 'json',
    success: function(result) {
        alert(result.Result);
    }
});

server

def urll(request):

if request.is_ajax():
    if request.method == 'POST':
        print ('Raw Data:', request.body) 

        print ('type(request.body):', type(request.body)) # this type is bytes

        print(json.loads(request.body.decode("utf-8")))

回答 6

HTTP POST有效负载只是一堆字节。Django(与大多数框架一样)通过URL编码参数或MIME多部分编码将其解码为字典。如果仅将JSON数据转储到POST内容中,则Django将不会对其进行解码。从完整的POST内容(而不是字典)中进行JSON解码;或将JSON数据放入MIME多部分包装器中。

简而言之,请显示JavaScript代码。问题似乎在那里。

The HTTP POST payload is just a flat bunch of bytes. Django (like most frameworks) decodes it into a dictionary from either URL encoded parameters, or MIME-multipart encoding. If you just dump the JSON data in the POST content, Django won’t decode it. Either do the JSON decoding from the full POST content (not the dictionary); or put the JSON data into a MIME-multipart wrapper.

In short, show the JavaScript code. The problem seems to be there.


回答 7

request.raw_post_data已不推荐使用。使用request.body替代

request.raw_post_data has been deprecated. Use request.body instead


回答 8

这样的事情。它的工作原理:从客户端请求数据

registerData = {
{% for field in userFields%}
  {{ field.name }}: {{ field.name }},
{% endfor %}
}


var request = $.ajax({
   url: "{% url 'MainApp:rq-create-account-json' %}",
   method: "POST",
   async: false,
   contentType: "application/json; charset=utf-8",
   data: JSON.stringify(registerData),
   dataType: "json"
});

request.done(function (msg) {
   [alert(msg);]
   alert(msg.name);
});

request.fail(function (jqXHR, status) {
  alert(status);
});

在服务器上处理请求

@csrf_exempt
def rq_create_account_json(request):
   if request.is_ajax():
       if request.method == 'POST':
           json_data = json.loads(request.body)
           print(json_data)
           return JsonResponse(json_data)
   return HttpResponse("Error")

Something like this. It’s worked: Request data from client

registerData = {
{% for field in userFields%}
  {{ field.name }}: {{ field.name }},
{% endfor %}
}


var request = $.ajax({
   url: "{% url 'MainApp:rq-create-account-json' %}",
   method: "POST",
   async: false,
   contentType: "application/json; charset=utf-8",
   data: JSON.stringify(registerData),
   dataType: "json"
});

request.done(function (msg) {
   [alert(msg);]
   alert(msg.name);
});

request.fail(function (jqXHR, status) {
  alert(status);
});

Process request at the server

@csrf_exempt
def rq_create_account_json(request):
   if request.is_ajax():
       if request.method == 'POST':
           json_data = json.loads(request.body)
           print(json_data)
           return JsonResponse(json_data)
   return HttpResponse("Error")

回答 9

html code 

file name  : view.html


    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
        $("#mySelect").change(function(){
            selected = $("#mySelect option:selected").text()
            $.ajax({
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json; charset=utf-8',
                url: '/view/',
                data: {
                       'fruit': selected
                      },
                success: function(result) {
                        document.write(result)
                        }
        });
      });
    });
    </script>
    </head>
    <body>

    <form>
        <br>
    Select your favorite fruit:
    <select id="mySelect">
      <option value="apple" selected >Select fruit</option>
      <option value="apple">Apple</option>
      <option value="orange">Orange</option>
      <option value="pineapple">Pineapple</option>
      <option value="banana">Banana</option>
    </select>
    </form>
    </body>
    </html>

Django code:


Inside views.py


def view(request):

    if request.method == 'POST':
        print request.body
        data = request.body
        return HttpResponse(json.dumps(data))
html code 

file name  : view.html


    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
        $("#mySelect").change(function(){
            selected = $("#mySelect option:selected").text()
            $.ajax({
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json; charset=utf-8',
                url: '/view/',
                data: {
                       'fruit': selected
                      },
                success: function(result) {
                        document.write(result)
                        }
        });
      });
    });
    </script>
    </head>
    <body>

    <form>
        <br>
    Select your favorite fruit:
    <select id="mySelect">
      <option value="apple" selected >Select fruit</option>
      <option value="apple">Apple</option>
      <option value="orange">Orange</option>
      <option value="pineapple">Pineapple</option>
      <option value="banana">Banana</option>
    </select>
    </form>
    </body>
    </html>

Django code:


Inside views.py


def view(request):

    if request.method == 'POST':
        print request.body
        data = request.body
        return HttpResponse(json.dumps(data))

回答 10

使用Angular您应该添加标头以请求或将其添加到模块配置标头: {'Content-Type': 'application/x-www-form-urlencoded'}

$http({
    url: url,
    method: method,
    timeout: timeout,
    data: data,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

Using Angular you should add header to request or add it to module config headers: {'Content-Type': 'application/x-www-form-urlencoded'}

$http({
    url: url,
    method: method,
    timeout: timeout,
    data: data,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

回答 11

request.POST只是一个类似于字典的对象,因此只需使用dict语法对其进行索引。

假设您的表单字段为fred,则可以执行以下操作:

if 'fred' in request.POST:
    mydata = request.POST['fred']

或者,使用表单对象处理POST数据。

request.POST is just a dictionary-like object, so just index into it with dict syntax.

Assuming your form field is fred, you could do something like this:

if 'fred' in request.POST:
    mydata = request.POST['fred']

Alternately, use a form object to deal with the POST data.