3

I am having trouble making POST requests from JavaScript to Wolfram Cloud APIs.

Here is a minimal example to reproduce the issue:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Test API</title>
    <script type="text/javascript">

    // Wolfram API
    fetch('https://www.wolframcloud.com/objects/c11abdbe-d203-406d-a6d3-a212d900c273', {
      method: 'POST',
      body: JSON.stringify({city1: 'London', city2:'Paris'}),
    })
    .then(response => response.json())
    .then(json => console.log(json))

    // Other Test API
    fetch('https://httpbin.org/post', {
      method: 'POST',
      body: JSON.stringify({city1: 'London', city2:'Paris'}),
    })
    .then(response => response.json())
    .then(json => console.log(json))

    </script>
  </head>
  <body>
    Testing the wolframcloud API
  </body>
</html>

The top fetch attempt is trying to call the Wolfram API introduced here https://reference.wolfram.com/language/workflow/DeployAWebAPI.html, but I get the error:

Failure: "The API could not be evaluated because there is no input for fields: \"city1\", \"city2\"."

However, the second fetch attempt with a different Test API succeeds with no issues.

Also, by comparison I have no problems calling the API from Python:

import urllib3

http = urllib3.PoolManager()

# Wolfram API
r1 = http.request('POST',
    'https://www.wolframcloud.com/objects/c11abdbe-d203-406d-a6d3-a212d900c273',
    fields={'city1': 'London', 'city2':'Paris'})
r1.status
r1.data

# Other Test API
r2 = http.request('POST',
    'http://httpbin.org/post',
    fields={'city1': 'London', 'city2':'Paris'})
r2.status
r2.data

So I wonder whether this is an issue specific to the interaction between JavaScript and Wolfram APIs? Thanks!

1 Answers1

3

You have the wrong content type header in your request. Apparently, it expects 'application/x-www-form-urlencoded', so this will work:

const url = "https://www.wolframcloud.com/objects/c11abdbe-d203-406d-a6d3-a212d900c273";

const params = {city1: 'London', city2:'Paris'}

const encodeBody = params => Object
  .keys(params)
  .map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
  .join('&');


fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
  },
  body: encodeBody(params)
})
.then(response => response.json())
.then(json => console.log(json))

You can look e.g. here for more details.

Leonid Shifrin
  • 114,335
  • 15
  • 329
  • 420