NiftyGateway URI lacks access-control-allow-origin: causing CORS errors when fetching. Workaround included.
This isn't really a bug in checkmynft per-se, but in any case it is preventing checkmynft from successfully checking (at least some) NFTs from NiftyGateway.
Contract: 0x3e88721fa41d5e102d54b4a04e550222efdd234d Token ID: 17700010001
HeroSection.js successfully retrieves the URI from the contract. The URI retrieved looks like this:
https://api.niftygateway.com/kygoopens/17700010001
Next, HeroSection.js proceeds to line 249, attempting to asynchronously fetch the URI above.
api.niftygateway.com at this point returns a 301 as follows:
< HTTP/2 301 < date: Sat, 27 Mar 2021 00:58:38 GMT < content-type: text/html; charset=utf-8 < content-length: 0 < set-cookie: AWSALB=8Crf0u1qzryQikKmBUOBFrxVZgIydQbA9UxK4JD3dt7WJWVPS0t91t8Ru7h4EWoN2CJhlrsYS1RRnxV5WYmeb4YiZ52ftpxCvxDPFZSTYippNq/eDEaVsZPbiDaT; Expires=Sat, 03 Apr 2021 00:58:38 GMT; Path=/ < set-cookie: AWSALBCORS=8Crf0u1qzryQikKmBUOBFrxVZgIydQbA9UxK4JD3dt7WJWVPS0t91t8Ru7h4EWoN2CJhlrsYS1RRnxV5WYmeb4YiZ52ftpxCvxDPFZSTYippNq/eDEaVsZPbiDaT; Expires=Sat, 03 Apr 2021 00:58:38 GMT; Path=/; SameSite=None; Secure < server: nginx < location: /kygoopens/17700010001/ < vary: Origin < strict-transport-security: max-age=3600 < x-content-type-options: nosniff < referrer-policy: same-origin
(above taken from doing curl -v https://api.niftygateway.com/kygoopens/17700010001)
Note what is missing from the above - there is no access-control-allow-origin: *
As a result of the missing access-control-allow-origin header, we see the following error at line 249 of HeroSection.js:
Access to fetch at 'https://api.niftygateway.com/kygoopens/17700010031' from origin 'https://checkmynft.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This is correct behavior from JS and from checkmynft - it is NiftyGateway's server that is misconfigured (that, or they are intentionally breaking scripts like checkmynft).
Here's a really ugly site-specific workaround to fix the problem. Insert the following (sans the let uriURL... part, which is just part of my test) into HeroSection.js like 249 and it works.
let uriURL = "https://api.niftygateway.com/kygoopens/17700010001"
let uriResponse;
try {
uriResponse = await fetch(uriURL, { method: "GET" });
} catch (e) {
try {
console.log("Regular fetch failed, attempting NiftyGateway hack...");
var niftyGatewayUriHack = uriURL.concat("/");
uriResponse = await fetch(niftyGatewayUriHack, { method: "GET" });
console.log(uriResponse.text());
} catch (e) {
console.error(e);
setFetchError(createMainError(nftAddress));
// setFetchError("Could not fetch NFT URI " + tokenURI);
setIsLoading(false);
return;
}
}
This works, because for whatever reason NiftyGateway does include the access-control-allow-origin: * header if one passes in the URI with / appended.
The above is really ugly, so I hesitate to submit a pull request for it, so I figured I'd file the issue first and see what y'alls thoughts are. If you like I'll file a pull request, or you could just paste it in yourself since it is relatively trivial (although tests should be added to of course).