-1

I'm trying to check if a photo link is returning a 404 or not.

I'm developing on localhost:xxxx, so I'm guessing this is a cross-origin issue.

I was originally getting No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:xxxx' is therefore not allowed access. I looked into that and installed this extension, which disables cross-origin resource sharing.

However after installing the extension, I am no longer getting the above error, but checking the status of the request always results in 0.

How should I go about solving this problem?

photo = 'http://example.com/apple.jpg';

var photoCheck = new XMLHttpRequest();
photoCheck.open('HEAD', photo, true);
photoCheck.send();
console.log(photoCheck.status); // Always returns 0
Valachio
  • 1,025
  • 2
  • 18
  • 40
  • `so I'm guessing this is a cross-origin issue` - exactly, with a CORS request that has no CORS response headers, status will always be 0 – Jaromanda X Jan 25 '18 at 04:26
  • 1
    Get rid of that extension, it's opening up your browser to a world of hurt. CORS isn't just protecting resources from people "stealing" them, it also protects you against malicious websites. Learn to deal with CORS issues. If you wrote the server, add cors headers, if not, use your own server to "proxy" your requests to the third party server – Jaromanda X Jan 25 '18 at 04:29
  • @JaromandaX How is the request still CORS, if the header is disabled? – Valachio Jan 25 '18 at 04:35
  • 1
    no, the header is not disabled at all - read what the extension does ***`Adds to response 'Allow-Control-Allow-Origin: *' header`*** - that's ENabled – Jaromanda X Jan 25 '18 at 04:37
  • @JaromandaX Understood. I'm still a bit confused though, is this a cross-origin issue, or is it another issue? – Valachio Jan 25 '18 at 04:41
  • 2
    it's the fact that xmlhttprequest is asynchronous, and you are checking status in the "wrong place" - you need to check in the `.onload` handler - BUT, if you do have CORS issues, then you'll also get status of zero always, though, not sure if onload would be called in that case – Jaromanda X Jan 25 '18 at 04:43
  • 1
    @Valachio it's both. You won't be able to make any requests from JavaScript to a resource on another origin unless the remote resource supports CORS (or you disable your browser's single-origin policy). And then, you need to wait for the request to complete before being able to properly read the status. – Phil Jan 25 '18 at 04:44
  • 1
    You could always just create an `` element and add `onload` and `onerror` handlers to detect if its `src` property loads correctly – Phil Jan 25 '18 at 04:48
  • @Phil Would I need to worry about cross-origin issues with the `` method? – Valachio Jan 25 '18 at 04:50
  • 1
    @Valachio nope :) – Phil Jan 25 '18 at 04:51

2 Answers2

2

You need to wait for the request to complete. The status will be 0 while the request is in progress. I would highly recommend using fetch which supports promises and generally makes requests easier

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

fetch('http://example.com/apple.jpg')
  .then(res => console.log(res.status))
Sidney
  • 4,495
  • 2
  • 18
  • 30
  • or, check the status in a callback https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload – Egy Mohammad Erdin Jan 25 '18 at 04:33
  • I don't believe this is the issue. If I set the synchronous issue to `false`, it still returns 0 – Valachio Jan 25 '18 at 04:34
  • EDIT - Sorry my mistake. You are right. I was checking the wrong thing. Setting synchronous to `false` does return the right code. – Valachio Jan 25 '18 at 04:44
2

As mentioned in the comments, I'd go about this a different way.

If you're looking at an online image, you can simply use an <img> element. This is allowed to be loaded from any domain (unless you try and bring in an http resource into an https page).

I'd try something like this...

function photoCheck(url) {
  return new Promise((resolve, reject) => {
    let img = document.createElement('img')
    img.onload = resolve
    img.onerror = reject
    img.src = url
  })
}

Then you can easily use

photoCheck('http://example.com/apple.jpg').then(() => {
  console.info('Image loads ok')
}, e => {
  console.warn('Image failed to load', e)
})
Phil
  • 157,677
  • 23
  • 242
  • 245
  • This is a better answer for my particular situation since I don't want to worry about cross-origin issues. With `fetch()`, I have to send a CORS request which will require me to do additional things on the backend when I go into production. – Valachio Jan 25 '18 at 16:18
  • Just out of curiosity, what if I'm using a div `background-image`? Since there is no built in `onload` and `onerror` functions, this method only works for `` right? – Valachio Jan 25 '18 at 16:18