Output all redirect headers and their status codes

Hi there,

I have been trying to figure it out alone but know that there are way smarter people than me in this community.

At the beginning of my workflow, I have a list of domains I need to check whether they are actually resolving. Not interested in the data the HTTP returns but in the headers. Here a simple HTTP Request node does the job perfectly (with some customizations for error handling).

At the same time, if the website I am making a request to redirects to another website/URL (eg. redirecting from HTTP:// to HTTPS:// or from non-www to www-version of the website), I want to get the redirect chain, with its corresponding values.

To illustrate the desired behavior, example flow would be:

Input domain - example.com
GET β€œhttp://example.com” ==>
==> response β€œ301” with a value of β€œhttps://example.com” ==>
==> response β€œ301” with a value of β€œhttps://www.example.com” ==>
==> response β€œ200” with a value of β€œhttps://www.example.com” (Stop here, since this is a final redirect)

And the output would be this redirect chain.

Basically, I want to see if I can replicate a similar behavior to https://httpstatus.io/ with N8N . At the end of the day, all that information already resides in N8N and I am trying to figure out how can I get info as an output.

Many thanks in advance!

So a simple way to get the redirect chain could be the https://deref.link/ service suggested by @Spacewalker:

This seems to be free and works well with n8n, so might be worth checking out. An even simpler alternative (which is also free for less than 500 requests per month) would be One Simple API for which @jon built a node recently.

None of these would provide the exact status codes though, so if you need to get these as well you would need to implement the logic yourself. This can get a bit messy though compared to the above. Here’s an example handling a single URL:

Example Workflow
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "url": "={{$json[\"url\"]}}",
        "responseFormat": "string",
        "dataPropertyName": "body",
        "options": {
          "fullResponse": true,
          "followAllRedirects": false,
          "followRedirect": false,
          "ignoreResponseCode": true
        }
      },
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        640,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "url",
              "value": "https://tinyurl.com/jy7ua4ey"
            }
          ]
        },
        "options": {}
      },
      "name": "Set URL",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        440,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"next_url\"]}}",
              "operation": "isEmpty"
            }
          ]
        }
      },
      "name": "Location Header Empty?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1040,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "url",
              "value": "={{$json[\"next_url\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set Redirect URL",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        440,
        160
      ]
    },
    {
      "parameters": {},
      "name": "Finished Looping",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1240,
        300
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "status",
              "value": "={{$json[\"statusCode\"]}}"
            },
            {
              "name": "next_url",
              "value": "={{$json[\"headers\"][\"location\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Data to Keep",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        840,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "let redirectList = []\n\nlet i = 0;\ndo {\n  try {\n    const items = $items(\"Data to Keep\", 0, i);\n    redirectList = redirectList.concat(items);\n  } catch (error) {\n    return redirectList;  \n  }\n  i ++;\n} while(true);\n\n\n"
      },
      "name": "Merge Data",
      "type": "n8n-nodes-base.function",
      "position": [
        1440,
        300
      ],
      "typeVersion": 1
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Set URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Data to Keep",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set URL": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Location Header Empty?": {
      "main": [
        [
          {
            "node": "Finished Looping",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Redirect URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Redirect URL": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Finished Looping": {
      "main": [
        [
          {
            "node": "Merge Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data to Keep": {
      "main": [
        [
          {
            "node": "Location Header Empty?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
1 Like

Hey @MutedJam !

This is awesome, I was trying to think of other terms to describe this process, and dereferencing is spot on! Thanks for the example workflow, it is of great help (for a long time wanted to understand how to build loops)

Now, this actually prompts me to see if there are any npm packages that I can include in my n8n build (already building an image as needed a few additional tools) to simply it.

OneSimpleAPI would be an option too but once you have over 500 requests, it will become prohibitively expensive for a fairly trivial need (following redirects).

Will tinker further and update the thread once I have more information!

2 Likes