12

I have a small tool build with Delphi that collects url's from a file or from the clipboard, and than builds a file called test.htm with a content like this :

<!DOCTYPE html> 
<html> 
<body> 
    <p>Click the button retrieve the links....</p> 
    <button onclick="myFunction()">Click me</button> 
    <p id="demo"></p> 
    <script> 
        function myFunction() { 
            window.open('http://www.speedtest.net/', '_blank');
            window.open('www.speedtest.net/', '_blank');
            and so on...
        }
    </script> 
</body>
</html>

The idea is to click on the button, and then a new tab (or window) is created for every url inside myFunction. This works, but with one small problem.

In the code example there are 2 url's, one with the http:// prefix and one without it. The first url works as expected and creates a new tab (or window) with the following url:

http://www.speedtest.net

The second 'window.open' does not work as I expected. This 'window.open' will create the following url in the new tab (or window)

file:///c:/myApplicaton/www.speedtest.net

As you have already figured out, the application is an executable in c:\myApplication

So my question(s) is, is there a way to use 'window.open' to create a new tab (or window) without putting the path of the application in front of the url ? If this is not possible with 'window.open', is there another way to do this ?

Or is the only way to do this to have the application put the http:// in front of every url that does not have it already ?

GuidoG
  • 11,359
  • 6
  • 44
  • 79
  • If you use only // instead of http:// is it working? You will have a problem with the https:// websites – romuleald Apr 16 '15 at 20:02
  • what does ^^ means ? – GuidoG Apr 16 '15 at 20:04
  • @GuidoG http://meta.stackexchange.com/a/25090 – Hypaethral Apr 16 '15 at 20:19
  • The question belongs to the community now so other developers can benefit from the answers. Don't be a child, these are just points in some virtual system. Sometimes mean people cast mean votes, so what? Don't make such a big deal out of it, nobody else does. – iMoses Apr 16 '15 at 20:20
  • I up voted you to zero, now all should be balanced within the universe :) – iMoses Apr 16 '15 at 20:23
  • 2
    @romuleald `//` is still a relative url and means 'use the same protocol as the main request', so for images in an `https` page, 'https' is used. In this case, the main page is a file, and the file protocol is used. If you use `//` at the start of the url, the popup will probably use `file://`, which is undesired given the nature of this application. – GolezTrol Apr 17 '15 at 09:10

5 Answers5

20

As you suggested, the only way is to add the http protocol to each URL which is missing it. It's a pretty simple and straightforward solution with other benefits to it.

Consider this piece of code:

function windowOpen(url, name, specs) {
    if (!url.match(/^https?:\/\//i)) {
        url = 'http://' + url;
    }
    return window.open(url, name, specs);
}

What I usually do is to also add the functionality of passing specs as an object, which is much more manageable, in my opinion, than a string, even setting specs defaults if needed, and you can also automate the name creation and make the argument optional in case it's redundant to your cause.

Here's an example of how the next stage of this function may look like.

function windowOpen(url, name, specs) {
    if (!url.match(/^https?:\/\//i)) {
        url = 'http://' + url;
    }
    // name is optional
    if (typeof name === 'object') {
        specs = name;
        name = null;
    }
    if (!name) {
        name = 'window_' + Math.random();
    }
    if (typeof specs === 'object') {
        for (var specs_keys = Object.keys(specs), i = 0, specs_array = [];
                i < specs_keys.length; i++) {
            specs_array.push(specs_keys[i] + '=' + specs[specs_keys[i]]);
        }
        specs = specs_array.join(',');
    }
    return window.open(url, name, specs);
}
Kevin B
  • 94,570
  • 16
  • 163
  • 180
iMoses
  • 4,338
  • 1
  • 24
  • 39
  • 1
    @Kevin B thanks, this is what happens when you don't test your code ;) – iMoses Apr 16 '15 at 20:21
  • if http is already there then url will become http://http://url. So we need to check http and https both. I would recommend function prependProtocol(url) { if (!url.match(/^https?:\/\//i) || !url.match(/^http?:\/\//i)) { url = 'http://' + url; } return url; } – Bhuvan Arora Apr 01 '19 at 05:01
  • @BhuvanArora that's incorrect. The regex "https?" catches both "http" and "https", because the question mark indicates that the "s" char is optional. In your example "htt://" will be a legit URL prefix, which is a bug. The code here works just fine. Please try it before jumping the gun. P.S. in the original example, in case the URL starts with either "http://" or "https://", a prefix won't be prepended. – iMoses Apr 01 '19 at 16:19
8

I think the best way would be to add "//" + url In this case - it isn't important, what protocol (http or https) you expect to receive as a result.

url = url.match(/^https?:/) ? url : '//' + url;
window.open(url, '_blank');
sergioneli
  • 206
  • 3
  • 3
5

The only way to do this is to have the application put the http:// in front of every url that does not have it already.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
5

For the behavior you're describing, you have to include your protocol with window.open. You could use a tertiary operator to simply include the protocol if it doesn't already exist:

url = url.match(/^http[s]?:\/\//) ? url : 'http://' + url;

Note that you'll need to use the SSL protocol sometimes, so this is not a complete solution.

Hypaethral
  • 1,467
  • 16
  • 22
  • If I understand what you mean, I've edited for clarity – Hypaethral Apr 16 '15 at 20:08
  • 1
    If you use '*', it would match multiple 's' as well. Better if you match only one 's': url = url.match(/^http[s]?:\/\//) ? url : 'http://' + url; – nicost Dec 13 '18 at 07:20
1

I made small changes function form answered by iMoses which worked for me.

Check for both https OR http protocol

if (!url.match(/^http?:\/\//i) || !url.match(/^https?:\/\//i)) {
        url = 'http://' + url;
    }

Hope it make more accurate for other situation !

Satish
  • 696
  • 1
  • 11
  • 22