2017-05-07 2 views
2

Ich habe die folgende Flasche Routing einrichten:Bottle.py - „Nein" Access-Control-Allow-Origin-Header auf die angeforderte Ressource vorhanden ist“

import tornado 
from bottle import route, run, hook, response 
import cudpred as cp 

_allow_origin = '*' 
_allow_methods = 'PUT, GET, POST, DELETE, OPTIONS' 
_allow_headers = 'Authorization, Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token' 

@hook('after_request') 
def enable_cors(): 
    '''Add headers to enable CORS''' 

    response.headers['Access-Control-Allow-Origin'] = _allow_origin 
    response.headers['Access-Control-Allow-Methods'] = _allow_methods 
    response.headers['Access-Control-Allow-Headers'] = _allow_headers 

@route('/', method = 'OPTIONS') 
@route('/<path:path>', method = 'OPTIONS') 
def options_handler(path = None): 
    return 

@route('/mapjson/<weekdaytopredict:int>/<hourtopredict:int>') 
def mapjson(weekdaytopredict=0, hourtopredict=0): 
    return cp.writeGeoJSON(weekdaytopredict, hourtopredict) 


@route('/preddt/<weekdaytopredict:int>/<hourtopredict:int>/<predictionmethod:int>/<normalization:int>') 
def preddt(weekdaytopredict=0, hourtopredict=0, predictionmethod =0, normalization=0): 
    return cp.predicitonCalculator(weekdaytopredict, hourtopredict, predictionmethod, normalization) 

run(server='tornado', host='0.0.0.0', port=2526, debug=False, reloader=True) 

Ich mache einen API-Aufruf durch ein HTML-<form> die mit einer JavaScript-Funktion verbunden ist, die dann die API-Aufrufe:

<form onSubmit=" return updateMap(event, document.getElementById('weekday').value, document.getElementById('hour').value, document.getElementById('method').value, document.getElementById('normalization').value)"> 
...</* Form />... 
</form> 

Und die JavaScript-Funktion ist:

function updateMap(e, weekday, hour, model, normalization){ 
    e.preventDefault(); 
    if (typeof(weekday) == 'undefined' || typeof(hour) == 'undefined' || weekday == '' || hour == '') { 
     mapurl = 'mymap.url'; 
    } else if(model == 0) { 
     mapurl = 'http://remote_machine:port/mapjson/' + weekday + '/' + hour 
    } else { 
     mapurl = 'http://remote_machine:port/preddt/' + weekday + '/' + hour + '/' + model + '/' + normalization 
    } 
    ...ETC... 
} 

Mein Problem ist, dass dies für den Anruf mapjson funktioniert, aber nicht für den Anruf preddt funktioniert. Jedes Mal, wenn ich wieder einen Antrag auf mapjson laufen, es gibt die angeforderten Ausgabe ohne ein Problem, aber wenn ich den Zugriff auf http://remote_machine:port/preddt mit Parametern versuchen, erhalte ich:

XMLHttpRequest cannot load http://remote_machine:port/preddt/4/21/1/0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://my.hosted.website.com' is therefore not allowed access. The response had HTTP status code 500. 

Was soll ich fehlen, wie dieses Problem beheben?

Antwort

0

Der Schlüssel ist dies am Ende der Fehlermeldung Sie auf dem Laufenden: The response had HTTP status code 500

Ihre /preddt Route HTTP zurückkehr 500. Ihr Anruf zu cp.predicitonCalculator wahrscheinlich ist der Täter sein.

Ich bin überrascht, dass Sie Fehler in Ihrer Flaschenkonsole nicht gesehen haben; vielleicht legt Tornado sie in eine Protokolldatei? Ich würde nach einem suchen.

Andere einfache Dinge versuchen:

  • Probieren Sie es ohne Tornado laufen, um zu sehen, ob die Ursache für den Server-Fehler deutlicher wird, z.B. gedruckt auf der Konsole.

  • Set Flasche debug=True. (Sie haben es im Moment auf False gesetzt, nicht sicher, warum.)

  • Hit Ihren Server mit Curl, so dass Sie die HTTP-Antwort und die Header, direkter als mit einem Browser untersuchen können.

  • Um zu zeigen, dass es in der Tat cp.predicitonCalculator ist, ändern Sie Ihre preddt Funktion, um einfach eine Zeichenfolge zurückzugeben. Sie erhalten den HTTP 500-Fehler nicht mehr (und Ihre CORS-Header funktionieren).

(Auch auf längere Sicht kann ein after_request Haken nicht die robusteste Art und Weise zu set the CORS headers sein.)

Viel Glück.

Verwandte Themen