Ошибки Access-Control-Allow-Origin, даже если сервер REST устанавливает заголовок

#javascript #python #ajax #flask #cors

#javascript #python #ajax #flask #cors

Вопрос:

Я пытаюсь узнать о сервере REST и размещении сервера flask.

запуск curl по URL-адресу сервера, который я получаю:

 HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST, OPTIONS, GET, HEAD
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 21600
Content-Type: text/html; charset=utf-8
Date: Sat, 28 Jun 2014 07:08:41 GMT
Server: gunicorn/19.0.0
Content-Length: 36
Connection: keep-alive
 

Но когда я пытаюсь получить доступ к данным из него с другого URL-адреса, я получаю:

XMLHttpRequest не может загрузить —url сервера—. В запрошенном ресурсе отсутствует заголовок ‘Access-Control-Allow-Origin’. Источник — URL-адрес страницы — поэтому доступ запрещен.

Следующие коды, которые я до сих пор пытался получить, чтобы получить данные:

   var formData = new FormData();
  formData.append("name",username );
  formData.append("id", userid);

  var request = new XMLHttpRequest();
  request.open("POST", "my-server-url");
  request.send(formData);
  console.log("Running Create user")
  console.log("Status: " request.status);
  console.log("error: " request.error);
  console.log("responseText: " request.responseText);
 

ВОЗВРАТ

 Running Create user
Status: 0
error: undefined
responseText: 
 

Я пробовал использовать ajax и jquery, которые также завершаются неудачей с той же ошибкой, описанной выше

   $.ajax({  
            url:'--server url--',  
            type:'POST',
            data :  mydata,      
            dataType: 'JSON',
            success: function(data) { 
                  console.log(data)   
            }  
        }); 
 

также

   $.ajax({  
                url:'--server url--',  
                type:'POST',
                data :  mydata,      
                dataType: 'JSONP',
                async: false,
                success: function(data) { 
                      console.log(data)   
                }  
            }); 
 

Я использую фрагмент кроссдоменного декоратора в коде python.

Для примера обработки маршрута моего сервера:

 @app.route("/",  methods=['POST', 'GET', 'OPTIONS'])
@crossdomain(origin='*')
def create():
    if request.method == 'POST':
        name = request.form['name']
        id = request.form['id']
        #duplicate = collection.find_one({'name': name, 'token': token})
        duplicate = collection.find_one({'id': id})
        if not duplicate:
            data = {'name': name,
                    'id': id}
            collection.insert(data, safe=True)
            response= make_response({'status': 'created'}, 201)
            response.headers['Access-Control-Allow-Origin'] = "*"
            return response 
        else:
            response= make_response({'status': 'already exists'}, 302)
            response.headers['Access-Control-Allow-Origin'] = "*"
            return response
 

Комментарии:

1. Видите ли вы запрос ПАРАМЕТРОВ в консоли вашего браузера? Если да, можете ли вы запустить curl -XOPTIONS на своем сервере и опубликовать результат здесь?

2. @kojo Спасибо за ответ. Я, наконец, нашел обходной путь и решил проблему cors с отправкой FormData через ajax и настройкой processData: false,contentType: false, (теперь я пытаюсь понять, почему это работает :-))

Ответ №1:

Мне, наконец, удалось решить проблему, следующие изменения, которые я внес в код ajax

 var formData = new FormData();
formData.append("id", userid); 
$.ajax({
            url: '--server--',
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(data){
              //do something with data
              console.log(data)
            },
            error: function(e) {
                    //handle error
                    console.log(e)
                  }


          })
 

Мне также пришлось внести эти изменения на сервере:

 @app.route("/",  methods=['POST', 'GET', 'OPTIONS'])
@crossdomain(origin='*')
def create():
    if request.method == 'POST':
        name = request.form['name']
        id = request.form['id']
        #duplicate = collection.find_one({'name': name, 'token': token})
        duplicate = collection.find_one({'id': id})
        if not duplicate:
            data = {'name': name,
                    'id': id}
            collection.insert(data, safe=True)
            return jsonify({'status': 'created'}), 201
        else:
            return jsonify({'status': 'already exits'}), 302
 

Комментарии:

1. Таким образом, вы полностью избавились от требования CORS. Это не требуется, если тип POST, а Content-Type — application/x-www-form-urlencoded (как в вашем новом примере)