1

Running flask locally, trying to call:

@app.route('/foo_route', methods=['POST'])
@cross_origin(origin='*')
def foo():
    return redirect("https://www.google.com/")

And I get the following error:

XMLHttpRequest cannot load https://www.google.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:5000' is therefore not allowed access

I tried to use CORS as such:

app = Flask(__name__)
CORS(app)

along with the @cross_origin() on my route. What is going wrong here? I was reading this may be a chrome bug when running locally? .

shell
  • 1,647
  • 2
  • 17
  • 31
  • If you send "https" then you have to send also authentication details..And google.com not a authentication site.. why you are using https – SumanKalyan Sep 24 '16 at 05:58

2 Answers2

4

I was having this same problem too! It is not a Chrome bug, it is built into chrome for security. (Cross Origin Resource Sharing) is a header that has to be present in the apache httpd.conf or apache.conf or .htaccess configuration file. If you are on NGINX, you have to edit the defaults.conf or nginx.conf file It basically makes it so that the web server accepts HTTP requests from places other than its own domain. The "real" way to fix it is by actually going into the web server (via ssh) and editing the applicable .conf to include this header. If you are on apache, you would add Header set Access-Control-Allow-Origin "*" at the top of the file. After you do this, restart apache in order to make sure that your changes are saved (service httpd restart). If you are on NGINX use this configuration:

   #
# Wide-open CORS config for nginx
#
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        #
        # Om nom nom cookies
        #
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
}

Now, I imagine, given your example, that you don't have access to the web server (since you put google's url in the URL). This is where it gets tricky.

One of your options is to use http://www.whateverorigin.org/. It bypasses CORS and retrieves the data effectively. In order to use it, you would run:

$.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://google.com') + '&callback=?', function(data){
    alert(data.contents);
});

This retrieves the response regardless of the CORS present on the web server.

If you don't want to change any of your existing code and you are using Google Chrome, there is a way around this CORS issue. One thing that you can do is install this browser extension: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?utm_source=plus and you can bypass CORS and run your program.

Hope this works for you!

Amrit Baveja
  • 199
  • 1
  • 10
  • Thanks for your answer. Looking into it more, I think I'll just redirect from the client side (javascript). I'm not sure if thats good practice or not. Sending server url to client and then the client redirects. – shell Sep 24 '16 at 05:24
1

What I decided to do was to pass the url to the client and then have the client redirect.

@app.route('/foo_route', methods=['POST'])
@cross_origin(origin='*')
def foo():
    return "https://www.google.com/"

Then on the client (javascript):

window.location.href = serverSentUrl;
shell
  • 1,647
  • 2
  • 17
  • 31