Bug Tracker

Opened 11 years ago

Closed 11 years ago

Last modified 10 years ago

#11489 closed bug (invalid)

$.post() requires a value back

Reported by: [email protected] Owned by: [email protected]
Priority: low Milestone: None
Component: ajax Version: 1.7.1
Keywords: Cc:
Blocked by: Blocking:

Description

$.post("/Foo", { id: "2" } This will make Firefox state "no element found".

If on the server side there is: [HttpPost] public void Foo(int id) {

Nothing

}

However, if I switch the 'void' to 'bool' and return true, then it works: [HttpPost] public bool Foo(int id) {

return true;

} And Firefox does not say "no element found" anymore.

It seems that jQuery requires/expects a value to be returned by the server for the POST request. However, the server already returns HTTP 200 OK which should be enough.

Change History (44)

comment:1 Changed 11 years ago by Rick Waldron

#11490 is a duplicate of this ticket.

comment:2 Changed 11 years ago by Rick Waldron

#11491 is a duplicate of this ticket.

comment:3 Changed 11 years ago by Rick Waldron

Component: unfiledajax
Owner: set to [email protected]
Status: newpending

Thanks for taking the time to contribute to the jQuery project! Please provide a complete reduced test case on jsFiddle to help us assess your ticket!

Additionally, be sure to test against the "jQuery (edge)" version to ensure the issue still exists. To get you started, use this boilerplate: http://jsfiddle.net/FrKyN/ Open the link and click to "Fork" (in the top menu) to begin.

comment:4 Changed 11 years ago by anonymous

The only code on the client side is: $.post("/Foo", { id: "2" });

The other is on the server-side, return or not return. So not much to put on jsfiddle as this depends on a server to post to.

comment:6 Changed 11 years ago by anonymous

I am unable to reproduce it using jsfiddle and the echo service.

comment:7 Changed 11 years ago by Rick Waldron

Priority: undecidedlow
Resolution: invalid
Status: pendingclosed

Closing per OP

comment:8 Changed 11 years ago by anonymous

It is not possible to reproduce this with the echo service provided by jsfiddle because of limitations in jsfiddle. Namely it always returns a Content-Type header.

The bug occurs when the response does not contain a Content-Type header.

comment:9 Changed 11 years ago by Rick Waldron

This still sounds like an issue with your server software and not with jQuery.

comment:10 Changed 11 years ago by anonymous

No, this is a issue with jQuery.

The server behaves correct and sends 200 OK or 404 Not Found. jQuery should understand that, instead jQuery bugs out when a Content-Type isn't specified.

comment:11 Changed 11 years ago by dmethvin

If there's no content type, jQuery probably can't guess the dataType. Try providing it explicitly if you are unable to correct the problem of a missing content type on the server. That would be good practice regardless.

comment:12 Changed 11 years ago by anonymous

But I have nothing to return. Hence I don't need no content-type since there is no content served.

jQuery does a POST to do the server and the server saves the data and returns nothing except HTTP 200 OK.

Why should I have to specify a Content-Type when I am not returning any content?

comment:13 Changed 11 years ago by Rick Waldron

Could you try this...

What happens if you replace the the call to $.post with a $.ajax:

$.ajax({
  url: "/Foo", 
  data: { id: "2" }, 
  contentType: "application/x-www-form-urlencoded", 
  success: function() {
    console.log( "success" );
  },
  error: function(xhr, status, error) {
    console.log( xhr.status + ": " + xhr.statusText );
  }
})

comment:14 Changed 11 years ago by anonymous

I tried the above code by you (which uses a GET request).

It also results in "no element found" in the JavaScript console. Neither the success or error handlers seem to trigger though.

comment:15 Changed 11 years ago by Rick Waldron

Sorry, i actually forgot to explicitly specify the request type.

$.ajax({
  type: "POST", 
  url: "/Foo", 
  data: { id: "2" }, 
  contentType: "application/x-www-form-urlencoded", 
  success: function() {
    console.log( "success" );
  },
  error: function(xhr, status, error) {
    console.log( xhr.status + ": " + xhr.statusText );
  }
})

comment:16 Changed 11 years ago by anonymous

I tried your revised code (which now uses POST). I still get the same "no element found" in the JavaScript console. Neither the success or error handler gets triggered.

    public void Foo(int id)
    {
    }

comment:17 in reply to:  15 ; Changed 11 years ago by anonymous

Replying to rwaldron:

...

This bug is marked as invalid, but I am not convinced it is invalid.

comment:18 in reply to:  17 ; Changed 11 years ago by jaubourg

Replying to anonymous:

Replying to rwaldron:

...

This bug is marked as invalid, but I am not convinced it is invalid.

I'm not convinced either but we'd need a reduced test case to assess that.

comment:19 in reply to:  18 ; Changed 11 years ago by anonymous

Replying to jaubourg:

Replying to anonymous:

Replying to rwaldron:

...

This bug is marked as invalid, but I am not convinced it is invalid.

I'm not convinced either but we'd need a reduced test case to assess that.

Then please open the bug again. I've provided both client-side source code and server-side source code. Bug isn't difficult to reproduce. The testcase is small, but I have no server online. You can write run the source provided in C#/ASP.NET or re-write it trivially in PHP, Python, Ruby or anything.

<?php
header_remove("Content-Type");
?>

comment:20 in reply to:  19 ; Changed 11 years ago by jaubourg

We cannot (and will not) investigate bugs reports without a complete reduced test case (ie: some page and/or jsFiddle demonstrating the issue). Exception being a team member having a lot of free time and especially interested in the issue.

It's not about us not willing, it's about us needing to feed ourselves with one paid (and time-consuming) activity or another.

If you want a bug investigated, the bare minimum is to provide a complete reduced test case. If you don't, then you're asking for support (because we can't establish if you don't have a trivial error your side unless we engage in a dialogue with you) and the bug tracker is not the place for this (IRC is).

So, again, provide a complete reduced test case, not out-of-context code snippets or "good god, isn't it obvious you have a bug" remarks: we need something simple and verifiable before we invest time (first to determine if it IS a bug, then to determine if it warrants fixing -- ie, no trivial workaround --, then to determine a proper fix).

Again, there is nothing against you personally. It's just that I, as an example, cannot take 20 minutes of my time on every ajax bug report just to explain why we need a reproducible test case (like I just did). So think about actually investigating them all.

Help us help you: provide a complete reduced test case.

Replying to anonymous:

Replying to jaubourg:

Replying to anonymous:

Replying to rwaldron:

...

This bug is marked as invalid, but I am not convinced it is invalid.

I'm not convinced either but we'd need a reduced test case to assess that.

Then please open the bug again. I've provided both client-side source code and server-side source code. Bug isn't difficult to reproduce. The testcase is small, but I have no server online. You can write run the source provided in C#/ASP.NET or re-write it trivially in PHP, Python, Ruby or anything.

<?php
header_remove("Content-Type");
?>

comment:21 in reply to:  20 Changed 11 years ago by anonymous

Replying to jaubourg:

We cannot (and will not) investigate bugs reports without a complete reduced test case (ie: some page and/or jsFiddle demonstrating the issue). Exception being a team member having a lot of free time and especially interested in the issue.

I do not need support, I can workaround this bug by adding a Content-Type header or using bool instead of void.

I do understand you want a jsfiddle, but it is not possible to create a fiddle for this as jsfiddle always provides a header and does not have any support for removing modifying HTTP headers.

comment:22 Changed 11 years ago by anonymous

thx for providing the workaround. friggin error was driving me crazy.

comment:23 Changed 11 years ago by Eldmannen

Replying to rwaldron:

Sorry, i actually forgot to explicitly specify the request type.

Now this bug have been independently confirmed (by the above poster).

Replying to jaubourg:

...

Now this bug have been independently confirmed (by the above poster).

comment:24 in reply to:  23 Changed 11 years ago by jaubourg

Resolution: invalid
Status: closedreopened

And as expected, I lost an hour trying to reproduce to no avail. The following test passes:

test( "jQuery.ajax - empty response with no ContentType should succeed", function() {

	stop();

	expect( 1 );

	jQuery.ajax( url( "data/emptyNoContentType.php" ), {
		success: function( data ) {
			strictEqual( data, "", "empty response with no content type should return success with empty string" );
		},
		error: function() {
			ok( false, "error" );
		},
		complete: function() {
			start();
		}
	});

});

with emptyNoContentType.php being:

<?php

header( "Content-Type:" );

(only way to neuter Content-Type in apache apparently: if you use header_remove( "Content-Type" ), apache will just add text/html on my local config)

Before I get shouted on, I also tested adding the following snippet, directly in ajax.js (line #458) to test responses with no content-type:

try {
	delete responseHeaders[ "content-type" ];
} catch( e ) {}

No failure... and it also works with dataType: "json" (provides null to the success callback instead of "").

So, again, unless we get a reduced test case, this will stay as closed (and worksforme to boot).

The problem most probably lies in some arcane microsoft server config/behaviour that setting the Content-Type explicitly seems to solve.

Replying to Eldmannen:

Replying to rwaldron:

Sorry, i actually forgot to explicitly specify the request type.

Now this bug have been independently confirmed (by the above poster).

Replying to jaubourg:

...

Now this bug have been independently confirmed (by the above poster).

comment:25 Changed 11 years ago by jaubourg

Resolution: worksforme
Status: reopenedclosed

comment:26 Changed 11 years ago by anonymous

Here is a test case.

http://lab.foreningshuset.se/

comment:27 in reply to:  25 ; Changed 11 years ago by anonymous

Replying to jaubourg: See the test case.

comment:28 in reply to:  27 ; Changed 11 years ago by jaubourg

Replying to anonymous:

Replying to jaubourg: See the test case.

What am I supposed to see? Nothing ever show in the console (tested in Firefox, Chrome and IE). If there actually is a bug, why on earth is it so difficult to make a test case that demonstrates it?

comment:29 in reply to:  28 Changed 11 years ago by anonymous

Replying to jaubourg:

Replying to anonymous:

Replying to jaubourg: See the test case.

What am I supposed to see? Nothing ever show in the console (tested in Firefox, Chrome and IE). If there actually is a bug, why on earth is it so difficult to make a test case that demonstrates it?

On Chrome and IE, I can't get anything either. But in Firefox 11, it shows up "no element found" when pressing the 'Does not work' button. It shows up in the Ctrl+Shift+K web console.

http://img109.imageshack.us/img109/7460/jquery.png

comment:30 Changed 11 years ago by jaubourg

The firefox only thing should have a red hearing right from the start. Here is what a 2 seconds search on google got me: http://stackoverflow.com/questions/975929/firefox-error-no-element-found?answertab=votes#tab-top (search terms: "firefox no element found in console").

Version 0, edited 11 years ago by jaubourg (next)

comment:31 Changed 11 years ago by jaubourg

Resolution: worksforme
Status: closedreopened

comment:32 Changed 11 years ago by jaubourg

Resolution: invalid
Status: reopenedclosed

comment:33 Changed 11 years ago by Rodrigo Rosenfeld Rosas <[email protected]…>

Okay, I've also first thought this was a jQuery issue and that was how I found this issue. But it turned out that the problem was in my application.

Here is a sample server that won't send the content-type header:

https://github.com/rosenfeld/jquery-ajax-callback-example

This code hosted on Heroku:

http://jquery-ajax-callback.heroku.com/

In my case, I was serving a "remove" action with "head :ok" in a Rails application. But due to a strange issue with CoffeeScript, instead of '/fields/remove/1', I was sending '/fields/remove/1.json' and hence Rails was setting the dataType to 'application/json' even so I thought it wouldn't. Here is the CoffeeScript issue that made me confused:

https://github.com/jashkenas/coffee-script/issues/947

comment:34 Changed 10 years ago by anonymous

I think the case is jQuery wants a return value though I couldn't prove it one way or the other.

I didn't want to change the content type for this one thing so I simply changed the 'void' to a 'bool' that always returns true and all is well.

comment:35 Changed 10 years ago by anonymous

Yes, changing it from 'void' to 'bool' does work, because it makes ASP.NET return 'true' or 'false' as output.

I think jQuery ought to accept an empty body too, so the server can just send the HTTP status code.

comment:36 Changed 10 years ago by dmethvin

Please stop attaching vague problem descriptions to closed bugs. If you have a test case and specific issue, open a new ticket. However, I suggest you start by asking on a forum to ensure is isn't a problem in your application.

comment:37 in reply to:  36 Changed 10 years ago by anonymous

Replying to dmethvin:

Please stop attaching vague problem descriptions to closed bugs. If you have a test case and specific issue, open a new ticket. However, I suggest you start by asking on a forum to ensure is isn't a problem in your application.

I just replied to the post by anonymous, it was not me who posted here.

I think many people experienced this bug, this is reproducible and not a bug in a application, it is a bug in jQuery.

jQuery does not allow empty bodies as a response from $.post(), even though it is valid, as a user may want to return only HTTP status code, without any content.

comment:38 Changed 10 years ago by dmethvin

This is where vague problem descriptions don't help, but I will take a guess.

If the server is responding with Content-Type: application/json then an empty response (no characters) is not valid JSON, which you can determine by trying JSON.parse(""). The server should either return a different content type or send a valid JSON response such as {} or null for the response body.

If my guess was wrong and this is not what is happening, then see my previous comment. Discuss the issue on a forum to ensure it's valid, create a test case, and make a new ticket .

comment:39 in reply to:  38 Changed 10 years ago by anonymous

Replying to dmethvin:

If the server is responding with Content-Type: application/json then an empty response (no characters) is not valid JSON, which you can determine by trying JSON.parse(""). The server should either return a different content type or send a valid JSON response such as {} or null for the response body.

This happens when the ASP.NET functions is declared as 'public void', hence the server would not respond with the Content-Type application/json.

comment:40 Changed 10 years ago by dmethvin

If my guess was wrong and this is not what is happening, then see my previous comment. Discuss the issue on a forum to ensure it's valid, create a test case, and make a new ticket .

comment:41 Changed 10 years ago by anonymous

I've now compared the output of public bool to public void.

The difference is that public bool methods outputs additional headers that public void methods does not.

Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding

Unless it has todo with Content-Length of void being 0.

It seems jQuery has a problem handling responses which does not include a Content-Type header.

public bool DoesWork()

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcam9uYXRoYW4uZmh1c2V0XGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTJcUHJvamVjdHNcTXZjQXBwbGljYXRpb24zXE12Y0FwcGxpY2F0aW9uM1xIb21lXEJvb2w=?=
X-Powered-By: ASP.NET
Date: Mon, 11 Feb 2013 14:10:27 GMT
Content-Length: 123

public void DoesNotWork()

HTTP/1.1 200 OK
Cache-Control: private
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcam9uYXRoYW4uZmh1c2V0XGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTJcUHJvamVjdHNcTXZjQXBwbGljYXRpb24zXE12Y0FwcGxpY2F0aW9uM1xIb21lXFZvaWQ=?=
X-Powered-By: ASP.NET
Date: Mon, 11 Feb 2013 14:10:01 GMT
Content-Length: 0

comment:42 Changed 10 years ago by anonymous

This can not be reproduced in PHP, because header_remove(), header_remove("Content-Type"), header_remove("Content-Length"); does not remove the Content-Type and Content-Length headers.

However, if you do header('Content-Type:'); you can actually get rid of the Content-Type header. But this does not work for the Content-Length header.

So the problem seems to be that jQuery expects a Content-Length header.

comment:43 Changed 10 years ago by anonymous

Note that the "no element found" entry only shows in Ctrl+Alt+K, and not in the Firebug console.

comment:44 Changed 10 years ago by anonymous

I've been able to successfully reproduce this under not only ASP.NET but also on PHP.

<?php

function main() {
?>
<script src="jquery-1.9.0.js"></script>
<input type="button" id="moo" value="meow">
<script>
$('#moo').on('click', function() {
  console.log('Button pressed');
  $.post('?op=test', { id: '2' });
});
</script>
<?php
}

function meow() {
  header('Content-Type:');
}

switch($_GET['op']) {
  case "test":
    meow();
    break;
  default:
    main();
    break;
}

?>
Note: See TracTickets for help on using tickets.