Cli: function redirects are not working with netlify dev

Created on 9 May 2020  ยท  18Comments  ยท  Source: netlify/cli

Note: I'm still working on a minimal reproduction, but you can check on the live site.


Do you want to request a _feature_ or report a _bug_?

๐Ÿ› bug

What is the current behavior?

First, see this Twitter discussion with @jlengstorf.

I defined the following redirect in netlify.toml.

[[redirects]]
    from = "/api/*"
    to = "/.netlify/functions/:splat"
    status = 200

Then in my application I have a serverless function located at /.netlify/functions/subscribe.
I hit it via a POST request using the browser's fetch API like this.

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

const response = await fetch("/api/subscribe", options)

It returns an HTML document rather than the expected JSON output.

<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><meta name="note" content="environment=development"/><title data-react-helmet="true"></title><link href="https://fonts.googleapis.com/css?family=Inter|Roboto|Patua+One" rel="stylesheet"/><style type="text/css">
    .anchor.before {
      position: absolute;
      top: 0;
      left: 0;
      transform: translateX(-100%);
      padding-right: 4px;
    }
    .anchor.after {
      display: inline-block;
      padding-left: 4px;
    }
    h1 .anchor svg,
    h2 .anchor svg,
    h3 .anchor svg,
    h4 .anchor svg,
    h5 .anchor svg,
    h6 .anchor svg {
      visibility: hidden;
    }
    h1:hover .anchor svg,
    h2:hover .anchor svg,
    h3:hover .anchor svg,
    h4:hover .anchor svg,
    h5:hover .anchor svg,
    h6:hover .anchor svg,
    h1 .anchor:focus svg,
    h2 .anchor:focus svg,
    h3 .anchor:focus svg,
    h4 .anchor:focus svg,
    h5 .anchor:focus svg,
    h6 .anchor:focus svg {
      visibility: visible;
    }
  </style><script>
    document.addEventListener("DOMContentLoaded", function(event) {
      var hash = window.decodeURI(location.hash.replace('#', ''))
      if (hash !== '') {
        var element = document.getElementById(hash)
        if (element) {
          var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
          var clientTop = document.documentElement.clientTop || document.body.clientTop || 0
          var offset = element.getBoundingClientRect().top + scrollTop - clientTop
          // Wait for the browser to finish rendering before scrolling.
          setTimeout((function() {
            window.scrollTo(0, offset - 0)
          }), 0)
        }
      }
    })
  </script><link rel="preconnect" href="https://instagram.com"/><script src="/socket.io/socket.io.js"></script></head><body><div id="___gatsby"></div><script>
        window.gatsbyLoadInstagram = function() {
          var js = document.createElement('script');
          var firstScript = document.getElementsByTagName('script')[0];
          js.id = 'gatsby-plugin-instagram';
          js.src = 'https://instagram.com/embed.js';

          firstScript.parentNode.insertBefore(js, firstScript);

          return true;
        }
      </script><script src="/commons.js"></script>
</body></html>

So it seems like the netlify dev command does not respect function redirects.

If the current behavior is a bug, please provide the steps to reproduce.

First get the project up and running.

git clone https://github.com/bradgarropy/dailytexascountry.com.git
cd dailytexascountry.com
npm install
netlify dev

Then go to the /store page and enter your email, which will kick off the API call to /api/subscribe.
Check the Network tab to see the unexpected HTML response.

What is the expected behavior?

The /api/subscribe endpoint should return a JSON object.

Local Environment Information

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
 Environment Info   โ”‚
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

  System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
  Binaries:
    Node: 12.13.1 - D:\nodejs\node.EXE
    Yarn: 1.22.4 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.5 - D:\nodejs\npm.CMD
  Browsers:
    Edge: 44.18362.449.0

netlify-cli/2.50.0 win32-x64 node-v12.13.1
functions bug

All 18 comments

@bradgarropy there was a Gatsby build error when I tried to run netlify dev. But running a static server with netlify dev --dir static, I was able to invoke the function correctly at http://localhost:8888/api/subscribe.

After running netlify dev locally, can you please try curl -vvv -d '{"something": true}' http://localhost:8888/api/subscribe and share the output!

@RaeesBhatti yea, the build requires some environment variables to be successful during data sourcing.

Here is the result of the curl command. It's the same HTML as returned from the deployed site.
Additionally, I have a console.log("SUBSCRIBE") as the very first line of my handler, but I don't see that logged in the terminal.

$ curl -X POST http://localhost:8888/api/subscribe -d '{"email": "[email protected]"}'
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><meta name="note" content="environment=development"/><title data-react-helmet="true"></title><link href="https://fonts.googleapis.com/css?family=Inter|Roboto|Patua+One" rel="stylesheet"/><style type="text/css">
    .anchor.before {
      position: absolute;
      top: 0;
      left: 0;
      transform: translateX(-100%);
      padding-right: 4px;
    }
    .anchor.after {
      display: inline-block;
      padding-left: 4px;
    }
    h1 .anchor svg,
    h2 .anchor svg,
    h3 .anchor svg,
    h4 .anchor svg,
    h5 .anchor svg,
    h6 .anchor svg {
      visibility: hidden;
    }
    h1:hover .anchor svg,
    h2:hover .anchor svg,
    h3:hover .anchor svg,
    h4:hover .anchor svg,
    h5:hover .anchor svg,
    h6:hover .anchor svg,
    h1 .anchor:focus svg,
    h2 .anchor:focus svg,
    h3 .anchor:focus svg,
    h4 .anchor:focus svg,
    h5 .anchor:focus svg,
    h6 .anchor:focus svg {
      visibility: visible;
    }
  </style><script>
    document.addEventListener("DOMContentLoaded", function(event) {
      var hash = window.decodeURI(location.hash.replace('#', ''))
      if (hash !== '') {
        var element = document.getElementById(hash)
        if (element) {
          var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
          var clientTop = document.documentElement.clientTop || document.body.clientTop || 0 
          var offset = element.getBoundingClientRect().top + scrollTop - clientTop
          // Wait for the browser to finish rendering before scrolling.
          setTimeout((function() {
            window.scrollTo(0, offset - 0)
          }), 0)
        }
      }
    })
  </script><link rel="preconnect" href="https://instagram.com"/><script src="/socket.io/socket.io.js"></script></head><body><div id="___gatsby"></div><script>
        window.gatsbyLoadInstagram = function() {
          var js = document.createElement('script');
          var firstScript = document.getElementsByTagName('script')[0];
          js.id = 'gatsby-plugin-instagram';
          js.src = 'https://instagram.com/embed.js';

          firstScript.parentNode.insertBefore(js, firstScript);

          return true;
        }
      </script><script src="/commons.js"></script></body></html>

However, when I hit the non-redirected URL, everything works as expected.

$ curl -X POST http://localhost:8888/.netlify/functions/subscribe -d '{"email": "bradgarropy 
@gmail.com"}'
{"subscription":{"id":2260910931,"state":"active","created_at":"2020-05-09T13:15:09.000Z","source":"API::V3::SubscriptionsController (external)","referrer":null,"subscribable_id":1378571,"subscribable_type":"form","subscriber":{"id":839901467}}}

@bradgarropy While netlify dev is running, can you try changing netlify.toml (add a new line or something). Can you see the following in terminal where netlify dev is running?

โ—ˆ Reloading redirect rules from [ 'netlify.toml' ]

@RaeesBhatti Yes, making any change to netlify.toml causes that log message.

Can you also make sure that no other instance of netlify dev is running. Just run pkill node and netlify dev and try the curl command again

Confirmed there is only version of node / netlify dev running. Same results with curl, redirect URL does not work, but /.netlify/functions/subscribe does.

$ ps -a
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
      754       1     754       6324  cons0     197609 13:38:17 /usr/bin/bash
      816     754     816       9476  cons0     197609 13:43:40 /usr/bin/sh
      775       1     775      11340  cons1     197609 13:42:17 /usr/bin/bash
      837     775     837      20288  cons1     197609 13:44:13 /usr/bin/ps
      823     816     816       7208  cons0     197609 13:43:41 /d/nodejs/node

Just did some more testing, looks like HTTP POST requests are not redirecting properly, but HTTP GET requests are.

I just tried this again on Window as well, and request rewrites and function invocation seem to be working fine for both GET and POST requests on [email protected].
Please share a reproduceable example of this, so that, I can track it down.

@RaeesBhatti, after further testing, seems as though Netlify's redirects are not working when using Gatsby! They work fine if you are using plain ole' HTML.

Here is the example repo, and the deployed site.

You'll notice that it works once deployed, but not using ntl dev.

I can confirm this issue on [email protected]. I've tested https://github.com/netlify/cli/pull/885 and it can't be reproduced on that branch. Thank you for providing the example. Please hold on until that PR is merged and released.

I'm having this same issue. Holding on for the new PR to be merged!!

Thanks for your hard work on this @RaeesBhatti! Any idea on when you will cut the release with the fix?

Thank you all for you patience. [email protected] has just been released which contains a fix for this issue.

Just updated to v2.51.0 and tested, everything works!

Just did some more testing, looks like HTTP POST requests are not redirecting properly, but HTTP GET requests are.

I'm currently experiencing this problem and have a new version of netlify installed:
netlify-cli/2.59.0 darwin-x64 node-v10.22.0

GET requests work fine, but POST requests stall. The request gets to my api server, but my handler is never called. I've got my redirect defined in a _redirects file like so:

/api/* http://localhost:5000/:splat 200

Am I missing something?

I've tried to see if it's my api server that's the problem by spinning up a simple test express server. That results in the same problem. I've inspected the difference between a successful request directly to the server and one that goes through the redirect. They look pretty identical, except for the origin.

When testing with a simple express server, I did notice that the on data event is never called, so my guess is that the body is not being forwarded with the redirect. Maybe that's causing problems since POST should have a body?


UPDATE: This bug needs to be reopened. I've just verified that the above doesn't happen with netlify/cli v2.51. I rolled back to that version since @RaeesBhatti said that version worked for him.

Thanks @michaelGregoire for reporting.

While the original issue is about redirecting to functions, I was able to reproduce your issue here:
https://github.com/erezrokah/netlify-build-reproductions/tree/cli/issue_890#netlify-build-reproductions

I'll follow up with an update once I have more information.

Thanks @erezrokah. I wasn't sure if I should open a new ticket or not.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iamskok picture iamskok  ยท  3Comments

karl-cardenas-coding picture karl-cardenas-coding  ยท  3Comments

TomPichaud picture TomPichaud  ยท  3Comments

rabbah picture rabbah  ยท  3Comments

designbuedchen picture designbuedchen  ยท  5Comments