When you send a request to a web server (click on a link), the server can send a number of different responses. Common examples are 404 (page not found), 403 (forbidden), or 500 (server error). Probably the most common response code is 200 (Ok), but you'll never see that one because it's generally accompanied by the page you were hoping to see.
There are a couple other codes at play here: 301 and 302. Codes 301 and 302 are redirect codes, and they tell your browser that the response you wanted has moved to another location. The main difference between them is how the browser caches things. A 301 code means "moved permanently", and the next time you try to visit the original link the browser may remember that the page has moved and go directly to the new location. 302 means "Found elsewhere" and will provide a link that your browser should use only temporarily.
It should be possible to write a program that will check a link, and as long as you keep getting 30x responses follow the response, until it finally gets a 200. At this point, rather than downloading the content it should show you the link.
Unfortunately, it's also more complicated than that. An Html page can also redirect to a new location using a meta tag in the page's head section that looks something like this: <meta http-equiv="refresh" content="0;url=NEW PAGE URL" />
. So such a program would already have to completely parse html to be sure we reach the last redirect.
Additionally, a page could redirect you further using javascript, and the javascript might be obfuscated. So now our hypothetical program also has to understand javascript. At this point we have a fully functional web browser. We're missing the small little detail of actually rendering a page to the screen, but our program has nearly everything else you need for a complete web browser, including all the accompanying security issues. You're no longer any better off than if you'd just clicked the link normally in the first place.
edit
to see the markdown source for how I did it.