Check if URL exists

Status
Not open for further replies.

p0_boy

anti-kumbaya
Veteran
Joined
Mar 26, 2019
Messages
64
Reaction score
29
First Language
English
Primarily Uses
RMMV
Hello, party people in the place to be-

I have the following Frankenstein function:

Code:
$._urlExists = function(url_to_check) {
        var result = false;
        // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
        var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
        '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
        switch (!!pattern.test(url_to_check)) {
            case true:
                // check if url exists, source: https://stackoverflow.com/a/24297372
                var reader = new XMLHttpRequest();
                reader.open('get', url_to_check, true);
                reader.onreadystatechange = (function() {
                    if (reader.readyState === 4) {
                        //check to see whether request for the file failed or succeeded
                        if ((reader.status == 200) || (reader.status == 0)) {
                            result = true;
                        };
                    };
                });
                reader.send(null);
            break;
        };
        return result;
    };
Unfortunately, it seems to return false even if I use a valid and existing URL.

I have a feeling this has to do with the function not waiting for the XMLHttpRequest to complete. Save inserting a manual wait command, is there a better way to wait for the request to complete before returning a result?

Otherwise, what am I doing wrong?

As ever, thank you in advance!
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,604
Reaction score
1,955
First Language
English
Primarily Uses
RMMV
Your code actually works; if you add a console.log to the if statement that sets result to true and display the value, it'll show "true", showing that both the URL was opened successfully and that the status code returned 200 or 0. However, your return result in the main function body is firing before the onreadystatechange event does, so it's showing false because it hasn't been set to true yet.

There is a way to return the result synchronously, but I haven't yet figured out how to make it work with your code.
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,125
Reaction score
10,637
First Language
Czech
Primarily Uses
RMMV
I have a feeling this has to do with the function not waiting for the XMLHttpRequest to complete
Absolutely spot on. Using events like onReadyStatChange means asynchronous programming, during which you cannot use the return function. The solution is simple.
Code:
if (reader.status == 200 || reader.status == 0) $gameSystem._realSite = true;
 

p0_boy

anti-kumbaya
Veteran
Joined
Mar 26, 2019
Messages
64
Reaction score
29
First Language
English
Primarily Uses
RMMV
Thank you @Trihan and @Poryg for the confirmation / explanation / and fix.

I tried @Poryg 's suggestion, but I am still coming up with a false value:

Here's the function, modified based on @Poryg 's fix:
Code:
$._urlExists = function(url_to_check) {
        $gameSystem._urlExists = false;
        // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
        var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
        '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
        '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
        switch (!!pattern.test(url_to_check)) {
            case true:
                // check if url exists, source: https://stackoverflow.com/a/24297372
                var reader = new XMLHttpRequest();
                reader.open('get', url_to_check, true);
                reader.onreadystatechange = (function() {
                    if (reader.readyState === 4) {
                        //check to see whether request for the file failed or succeeded
                        if ((reader.status == 200) || (reader.status == 0)) {
                            $gameSystem._urlExists = true;
                        };
                    };
                });
                reader.send(null);
            break;
        };
    };
I am calling it during Game Boot:
Code:
var _Scene_Boot_start = Scene_Boot.prototype.start;
    Scene_Boot.prototype.start = function() {
        _Scene_Boot_start.call(this);
        // get ip lookup services list
        var ip_lookup_url = $._ipLookupServicesURL();
        $._urlExists(ip_lookup_url);
        console.log($gameSystem._urlExists);
        if ($gameSystem._urlExists) $._getIPLookupServices(ip_lookup_url);
        console.log($gameSystem._IPLookupJSON);
    };
But it is still returning false.

Based on the terminology you introduced me to, a Google search revealed another Stackoverflow solution that uses async/await...
Code:
function getData() {
  return axios.get('https://jsonplaceholder.typicode.com/posts');
}

(async () => {
   console.log(await getData())
})()
But I am confused as to how I would implement it in my scenario. Does anybody have any pointers?

Thank you again!



Addendum:

I started reading about Promises and altered the code to this:
Code:
$._urlExists = function(url_to_check) {
    $gameSystem._urlExists = false;
    // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
    var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator

    if (!!pattern.test(url_to_check) == true) {
        return new Promise(function(resolve, reject) {
            var reader = new XMLHttpRequest();
            reader.open('get', url_to_check, true);
            reader.onreadystatechange = (function() {
                if (reader.readyState === 4) {
                    //check to see whether request for the file failed or succeeded
                    if ((reader.status == 200) || (reader.status == 0)) {
                        return resolve(true);
                    } else {
                        return resolve(false);
                    };
                };
            });
            reader.send(null);
        });
    };
};
Which seems to work, I just need to figure out how to parse the returned value... it's like a weird object:



Addendum 2:

It's not pretty or elegant, but this is how I got it to work in my Game Boot:
Code:
var _Scene_Boot_start = Scene_Boot.prototype.start;
    Scene_Boot.prototype.start = function() {
        _Scene_Boot_start.call(this);
        // get ip lookup services list
        var ip_lookup_url = $._ipLookupServicesURL();
        console.log(ip_lookup_url);
        var url_exists = $._urlExists(ip_lookup_url);
        console.log(url_exists);
        url_exists.then(function(value) {
          console.log(value);
          if (value === true) {
            var ip_lookup_json = $._getIPLookupServices(ip_lookup_url);
             console.log(ip_lookup_json);
            ip_lookup_json.then(function(json_data) {
              console.log(json_data);
              $gameSystem._IPLookupJSON = json_data;
            });
          };
        });
    };
 
Last edited:

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,293
Reaction score
11,710
First Language
English
Primarily Uses
RMVXA
[closed]IgnoreMe[/closed]
 
Status
Not open for further replies.

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

mlogan wrote on alltheyuriz's profile.
Please be aware that our Status rules ask members not to make more than 2 status updates in 24 hours.
rux
Just 80% of my motivation on game making lmao, anyone got tips on how to not be unmotivated?
I've signed up for a job training program for people with Asperger's Syndrome. I went to a "test run" today so they could see how well I did with simple jobs, and I amazed them. Most new people do it in 30+ minutes, while I finished in a mere 15 minutes. Gives me time to work on a screenplay for Studio MDHR...
People,I have seen that Someone from China/Chile and London is doing a Vaccine Against COVID-19.

Forum statistics

Threads
105,467
Messages
1,013,917
Members
137,108
Latest member
maxmach
Top