skip to Main Content

An ajax function from jQuery

$.ajax({
  method: "POST",
  url: "some.php",
  data: { name: "John", location: "Boston" }
})
  .done(function( msg ) {
    console.log( "Data Saved: " + msg );
  });

And this is a request using a fetch API

const data = { name: "John", data: "Boston" };
const options = {
    method: 'POST',
    headers: {
              'Content-Type': 'application/json',
             },
    body: data,
};

const response = await fetch('/api ',options);
const responseData = await response.json();
console.log(responseData);

Also how come this fetch implementation is producing an error in my node terminal ?

If I use a digit instead of ‘Boston’ for example the Unexpected token changes to ‘<‘ .

SyntaxError: Unexpected token o in JSON at position 1
    at JSON.parse (<anonymous>)

Is there anything I should watch out for between these two?

data of ajax and body of fetch?

(I am not using them simultaneously the way)

2

Answers


  1. 'Content-Type': 'application/json',
    

    You claim you are sending JSON.

    const data = { name: "John", data: "Boston" };
    
    body: data,
    

    data is an object, not JSON.

    When it gets forced into a string (because it isn’t a data type recognised by fetch so it gets converted to a string automatically) it becomes "[object Object]" which is still not JSON. (The [ starts an array and then the o is an error).


    If you want to send JSON, you need to convert to the object to JSON yourself. Use JSON.stringify.


    Also note that while the server-side code appears to be able to handle JSON input, jQuery sends application/x-www-form-urlencoded data, not JSON.

    So to match that you would need:

    var searchParams = new URLSearchParams();
    searchParams.append("name", "John");  
    searchParams.append("location", "Boston");
    
    const options = {
        method: 'POST',
        headers: {
                  'Content-Type': 'application/x-www-form-urlencoded',
                 },
        body: searchParams.toString(),
    };
    
    const response = await fetch('/api ',options);
    const responseData = await response.json();
    console.log(responseData);
    
    Login or Signup to reply.
  2. From the documentation we can see that…

    When data is an object, jQuery generates the data string from the object’s key/value pairs unless the processData option is set to false. For example, { a: "bc", d: "e,f" } is converted to the string "a=bc&d=e%2Cf". If the value is an array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below). For example, { a: [1,2] } becomes the string "a%5B%5D=1&a%5B%5D=2" with the default traditional: false setting.

    fetch doesn’t do that. But separately, you’ve said you’re sending JSON by including Content-Type: application/json as a header, but you aren’t doing that (and your jQuery code doesn’t do that either, it sends URI-encoded data).

    You have to do it yourself. If you want to send JSON, use JSON.stringify:

    const options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
    };
    

    If you want to send URI-encoded data, use URLSearchParams:

    const data = new URLSearchParams([ // Note this is an array of
        ["name", "John"],              // [name, value] arrays
        ["data", "Boston"],
    ]);
    const options = {
        method: 'POST',
        body: data,
    };
    

    If you want to send standard form encoding, use FormData (exactly like the above, but with FormData instead of URLSearchParams.

    Also how come this fetch implementation is producing an error in my node terminal ?
    If I use a digit instead of ‘Boston’ for example the Unexpected token changes to ‘<‘ .

    SyntaxError: Unexpected token o in JSON at position 1
       at JSON.parse (<anonymous>)
    

    Because your object is being coerced to a string, and it coerces to "[object Object]", which is invalid JSON as of the o.


    Side note: Your fetch code is falling prey to a footgun in the API: fetch only rejects its promise on network error, not on HTTP error. You can’t assume that a fulfilled promise from fetch means your request was successful, you have to check:

    const response = await fetch('/api ',options);
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    const responseData = await response.json();
    console.log(responseData);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search