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,960
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,639
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,299
Reaction score
11,713
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

I should realize that error was produced by a outdated version of MZ so that's why it pop up like that
Ami
i can't wait to drink some ice after struggling with my illness in 9 days. 9 days is really bad for me,i can't focus with my shop and even can't do something with my project
How many hours have you got in mz so far?

A bit of a "sparkle" update to the lower portion of the world map. :LZSexcite:
attack on titan final season is airing tomorrow, I'm excited and scared at the same time!

Forum statistics

Threads
105,882
Messages
1,017,231
Members
137,607
Latest member
Maddo
Top