Question

I am trying to send some custom data with an ajax PUT request to the server but the data is not received on the server side. Following is the method that sends the request.

    // Send ajax request
    $.ajax({
        type: "PUT",
        url: "/some/url/",
        data: {'verbose': true},
        contentType: "application/json",

        // Callbacks
        success: function(response) {},
        error: function(response) {},
        complete: function(response) {},
    });

Following is the request object received by the server.

<WSGIRequest
path:/profile/cart/23/unsave/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{'_we_wk_ls_': '%7B%22time%22%3A1378973525509%2C%22luid%22%3A%2213789735255096b17d47fa3a67adb%22%7D',
 'csrftoken': '31qNsad14V33bovpnCnVh3WTaa44YQoM',
 'djdt': 'hide',
 'sessionid': 'qxpv1zshp05w777rfpr6mbl81irdzu3b'},
META:{'CELERY_LOADER': 'djcelery.loaders.DjangoLoader',
 'CLICOLOR': 'true',
 'COLORTERM': 'gnome-terminal',
 'COMPIZ_CONFIG_PROFILE': 'ubuntu',
 'CONTENT_LENGTH': '12',
 'CONTENT_TYPE': 'application/json; charset=UTF-8',
 u'CSRF_COOKIE': u'31qNsad14V33bovpnCnVh3WTaa44YQoM',
 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-EUBCf7VXvY,guid=5b8264e5a43262a19a9a7e1e00000039',
 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path',
 'DESKTOP_SESSION': 'ubuntu',
 'DISABLE_AUTO_TITLE': 'true',
 'DISPLAY': ':0',
 'DJANGO_SETTINGS_MODULE': 'config.devel',
 'GATEWAY_INTERFACE': 'CGI/1.1',
 'GDMSESSION': 'ubuntu',
 'GIO_LAUNCHED_DESKTOP_FILE': '/usr/share/applications/terminator.desktop',
 'GIO_LAUNCHED_DESKTOP_FILE_PID': '3100',
 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated',
 'GNOME_KEYRING_CONTROL': '/tmp/keyring-YjGbUi',
 'GNOME_KEYRING_PID': '2036',
 'GPG_AGENT_INFO': '/tmp/keyring-YjGbUi/gpg:0:1',
 'GREP_COLOR': '1;32',
 'GREP_OPTIONS': '--color=auto',
 'HOME': '/home/amyth',
 'HTTP_ACCEPT': 'application/json, text/javascript, */*; q=0.01',
 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
 'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.5',
 'HTTP_CONNECTION': 'keep-alive',
 'HTTP_COOKIE': 'csrftoken=31qNsad14V33bovpnCnVh3WTaa44YQoM; _we_wk_ls_=%7B%22time%22%3A1378973525509%2C%22luid%22%3A%2213789735255096b17d47fa3a67adb%22%7D; djdt=hide; sessionid=qxpv1zshp05w777rfpr6mbl81irdzu3b',
 'HTTP_HOST': '127.0.0.1:8000',
 'HTTP_REFERER': 'http://127.0.0.1:8000/some/url/',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
 'HTTP_X_CSRFTOKEN': '31qNsad14V33bovpnCnVh3WTaa44YQoM',
 'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
 'LANG': 'en_IN',
 'LANGUAGE': 'en_IN:en',
 'LC_CTYPE': 'en_IN',
 'LESS': '-R',
 'LOGNAME': 'amyth',
 'LSCOLORS': 'exfxcxdxbxegedabagacad',
 'LS_COLORS': 'di=38;5;222:fi=38;5;59:ln=38;5;116:ex=38;5;107:ow=48;5;33;38;5;230:tw=48;5;235;38;5;33',
 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path',
 'OLDPWD': '/home/amyth',
 'ORBIT_SOCKETDIR': '/tmp/orbit-amyth',
 'PAGER': 'less',
 'PATH': '/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/amyth/arcanist-repo/arcanist/bin',
 'PATH_INFO': u'/profile/cart/23/unsave/',
 'PWD': '/home/amyth/Projects/blob',
 'QT_ACCESSIBILITY': '1',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_HOST': '',
 'REQUEST_METHOD': 'PUT',
 'RUN_MAIN': 'true',
 'SCRIPT_NAME': u'',
 'SERVER_NAME': 'localhost',
 'SERVER_PORT': '8000',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.3',
 'SESSION_MANAGER': 'local/amyth-workbook:@/tmp/.ICE-unix/2047,unix/amyth-workbook:/tmp/.ICE-unix/2047',
 'SHELL': '/usr/bin/zsh',
 'SHLVL': '1',
 'SSH_AGENT_PID': '2087',
 'SSH_AUTH_SOCK': '/tmp/keyring-YjGbUi/ssh',
 'TERM': 'xterm-256color',
 'TERMINATOR_UUID': 'urn:uuid:44ae86d1-9d00-4bfa-ba5e-7aaf089a776f',
 'TZ': 'Asia/Calcutta',
 'UBUNTU_MENUPROXY': 'libappmenu.so',
 'USER': 'amyth',
 'WINDOWID': '67108868',
 'XAUTHORITY': '/home/amyth/.Xauthority',
 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/etc/xdg',
 'XDG_CURRENT_DESKTOP': 'Unity',
 'XDG_DATA_DIRS': '/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/',
 'XDG_SEAT_PATH': '/org/freedesktop/DisplayManager/Seat0',
 'XDG_SESSION_COOKIE': 'e3eb0e8427880c0282433b5a0000000a-1381740618.104950-1684525435',
 'XDG_SESSION_PATH': '/org/freedesktop/DisplayManager/Session0',
 '_': '/usr/bin/python',
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0xb73310d0>,
 'wsgi.file_wrapper': <class wsgiref.util.FileWrapper at 0x987de6c>,
 'wsgi.input': <socket._fileobject object at 0xb22387ac>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': True,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}>

But when I check the request headers in the browser I can see the data added to the REQUEST_PAYLOAD. Following is how it looks:

Request URL:http://127.0.0.1:8000/some/url/
Request Method:PUT
Status Code:200 OK
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:12
Content-Type:application/json
Cookie:_we_wk_ls_=%7B%22time%22%3A1378281143956%2C%22luid%22%3A%221378281143956452ac09ec7efaa23%22%7D; djdt=hide; PHPSESSID=fn7cliso1q9e3u9rk3dc4t8ra4; sessionid=4zc8di4r31w6siwy31frwu97t4z2on7w; csrftoken=RjmgBBv8IUQXhWwTVzoEhIhyLncU1OQN
Host:127.0.0.1:8000
Origin:http://127.0.0.1:8000
Pragma:no-cache
Referer:http://127.0.0.1:8000/profile/cart/
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
X-CSRFToken:RjmgBBv8IUQXhWwTVzoEhIhyLncU1OQN
X-Requested-With:XMLHttpRequest
Request Payload
verbose=true
Response Headersview source
Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin:*
Content-Type:application/json
Date:Wed, 16 Oct 2013 13:03:07 GMT
Server:WSGIServer/0.1 Python/2.7.3
Vary:Cookie

I have checked other questions on Stack Overflow and other blogs researching on the same and most of them suggest that the data should be sent with a PUT request. I also came across another question, answer for which suggested that it's a browser issue and this happens only in the latest version of chrome. I thought that might be it but I checked the same on FF and it does not work with FF as well.

Is this a bug, or am I doing something wrong? Any suggestions and/or help will be much appreciated.

Following is what I am using:

  • jQuery version 1.8.0
  • Django version 1.5
  • Chrome version 29.0.1547.76
  • Firefox version 24.0

Update 0.1

This is crazy, I tried changing the request to "POST" request and it still does not work. The data is not being passed with either of "POST" or "PUT" requests. It works with "GET" request though.

Update 0.2

if I remove contentType: "application/json", or change it to contentType: "application/x-www-form-urlencoded" the data is sent with the "POST" request but it still does not work with PUT requests. :/

Was it helpful?

Solution

It makes sense that it works when you remove application/json or change Content-Type to application/x-www-form-urlencoded.

Look at your request payload, you are sending a content type of application/json yet the body contains verbose=true and this is not JSON format. On the other hand, adding application/x-www-form-urlencoded fits the verbose=true format, hence it working again.

Your best bet is to use application/x-www-form-urlencoded while serializing your entire form.

OTHER TIPS

request.POST processes form-encoded data into a dictionary, which only makes sense for web browser form submissions. There is no equivalent for PUT, as web browsers don't PUT forms; the data submitted could have any content type. You'll need to get the raw data out of request.raw_post_data, possibly check the content type, and process it however makes sense for your application.

The properties PUT and DELETE arent in request object, with Django when you are working with ajax calls you need do it: def update(self, request, pk=None):

    if request.is_ajax():
           aux = QueryDict(request.body)
           idParameter = auxiliar['Parameter1']# Read variables of PUT
    .........................................................................
    .........................................................................
    .........................................................................

Happen the same with DELETE Method.

I just dug into this, and discovered that the mechanism in Django's WSGIRequest object that loads POST data has a clause that limits it exclusively to the POST method.

So to your initial question "Is this a bug ? Or am I doing something wrong" I would say neither. This is an unimplemented feature in Django's WSGI implementation.

I was unable to find anything useful in terms of discussion in the developers group or feature requests, so this seems like the community hasn't had any call to implement it yet.

For myself, I will be extending django.core.handlers.wsgi.WSGIRequest to load POST data, even if it is a PUT, and providing a custom WSGI handler for my project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top