Search code examples
javascriptapixmlhttprequestcorshttprequest

Understanding Page Response


I am trying to understand how the whole CORS policy works. To explain my confusion, let me give you an example:

$.get("https://www.google.com", function(response) { alert(response) });

The above request will return with the following error:

XMLHttpRequest cannot load https://www.google.com/. Redirect from 'https://www.google.com/' to 'https://www.google.ca/?gfe_rd=cr&ei=TlqUWeGEH5HRXqW6utgI' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fiddle.jshell.net' is therefore not allowed access.

Now in order for that to work, google would have to white-list https://fiddle.jshell.net.

Now, if I were to try the same thing on a restful API page, that will work. My question is really simple, Why?

Trying to analyze this, I tried hitting an API and analyzing its response:

https://apigee.com/console/bing?req=%7B%22resource%22%3A%22web_search%22%2C%22params%22%3A%7B%22query%22%3A%7B%22query%22%3A%22sushi%22%2C%22sources%22%3A%22web%22%7D%2C%22template%22%3A%7B%22format%22%3A%22json%22%7D%2C%22headers%22%3A%7B%7D%2C%22body%22%3A%7B%22attachmentFormat%22%3A%22mime%22%2C%22attachmentContentDisposition%22%3A%22form-data%22%7D%7D%2C%22verb%22%3A%22get%22%7D

Response:

HTTP/1.1 200
Date:
Wed, 16 Aug 2017 14:31:32 GMT
Content-Length: 266
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Server: Apigee Router
X-Content-Type-Options: nosniff

I came to conclusion that it must be the headers. Specifically I belive that it is this header: Content-Type: application/json; But I don't know for sure, I am trying to understand this and hoping somebody here can explain to me.


Solution

  • So I did 2 tests: running your code $.get("https://www.google.com", function(response) { alert(response) }); snippet from the console and requesting https://www.google.com from https://apigee.com/console/others

    I think what happens in the 1st case is the fact that the request is done from the client, next request headers are sent:

    :authority:www.google.com
    :method:GET
    :path:/?_=1502896196820
    :scheme:https
    accept:*/*
    accept-encoding:gzip, deflate, br
    accept-language:en-US,en;q=0.8
    origin:https://stackoverflow.com
    referer:https://stackoverflow.com/questions/45717044/understanding-page-response
    user-agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3187.0 Safari/537.36
    x-chrome-uma-enabled:1
    x-client-data:CJG2yQEIo7bJAQiMmMoBCKudygEIs53KAQjRncoBCKiiygE=
    

    Since Google does not reply with 'Access-Control-Allow-Origin: *' - client, and in the request I have origin:https://stackoverflow.com, Chrome in my case throws CORS error.

    In the 2nd test, using https://apigee.com/console/others and requesting https://www.google.com , apigee.com seems to overwrite headers and sends:

    GET / HTTP/1.1
    Host:
    www.google.com
    X-Target-URI:
    https://www.google.com
    Connection:
    Keep-Alive
    

    Also, from DEV console, I can see it does server to server call so no client involved in throwing CORS, thus I am getting the responses with Google page.

    UPDATE:

    Regarding JSON API requests, here is some interesting info from Google CloudPlatform about CORS

    Note: CORS configuration applies only to XML API requests. For JSON API requests, Cloud Storage returns the Access-Control-Allow-Origin header with the origin of the request.

    Thus, if the request is performed from the client, a client should not throw CORS errors since it gets Access-Control-Allow-Origin with the same origin it sent.

    However, different APIs and clients might process requests differently. Thus, sometimes Firefox throws CORS while Chrome does not.