5

Ich arbeite an einer Webanwendung, die auf einer erholsamen API basiert, die mit Pythons CherryPy-Framework geschrieben wurde. Ich begann mit dem Schreiben der Benutzeroberfläche mit einer Kombination aus jQuery und serverseitigen Vorlagen, wechselte aber schließlich zu Backbone.js, weil die jQuery außer Kontrolle geriet.Hinzufügen von HTTP-Basisauthentifizierungs-Header zu Backbone.js Synchronisierungsfunktion Verhindert, dass das Modell bei Save() aktualisiert wird

Leider habe ich Probleme, meine Modelle mit dem Server zu synchronisieren. Hier ist ein kurzes Beispiel aus meinem Code:

$(function() { 
    var User = Backbone.Model.extend({ 
     defaults: { 
      id: null, 
      username: null, 
      token: null, 
      token_expires: null, 
      created: null 
     }, 

     url: function() { 
      return '/api/users'; 
     }, 

     parse: function(response, options) { 
      console.log(response.id); 
      console.log(response.username); 
      console.log(response.token); 
      console.log(response.created); 
      return response; 
     } 
    }); 

    var u = new User(); 
    u.save({'username':'asdf', 'token':'asdf'}, { 
     wait: true, 
     success: function(model, response) { 
      console.log(model.get('id')); 
      console.log(model.get('username')); 
      console.log(model.get('token')); 
      console.log(model.get('created')); 
     } 
    }); 
}); 

Wie Sie wahrscheinlich sagen können, hier ist die Idee, einen neuen Benutzer mit dem Dienst zu registrieren. Wenn ich u.save(); rufe, sendet Backbone tatsächlich eine POST-Anfrage an den Server. Hier sind die entsprechenden Bits:

Anfrage:

Request URL: http://localhost:8080/api/users 
Request Method: POST 
Request Body: {"username":"asdf","token":"asdf","id":null,"token_expires":null,"created":null} 

Antwort:

Status Code: HTTP/1.1 200 OK 
Content-Type: application/json 
Content-Length: 109 
Response Body: {"username": "asdf", "created": "2013-02-07T13:11:09.811507", "token": null, "id": 14, "token_expires": null} 

Wie Sie sehen können, der Server erfolgreich verarbeitet die Anforderung und sendet eine id zurück und ein Wert für created. Aber aus irgendeinem Grund, wenn mein Code ruft console.log(u.id);, bekomme ich null, und wenn mein Code console.log(u.created); ruft, bekomme ich undefined.

tl; dr: Warum behält Backbone.js persistent Änderungen an meinen Objekten nach einem Anruf an save()?

Edit: ich den obigen Code geändert haben, so dass die Modell-Eigenschaften zugegriffen werden, um die Funktion get in einem success Rückruf verwenden. Dies sollte alle Nebenläufigkeitsprobleme mit dem ursprünglichen Code lösen.

Ich habe auch einige Konsolenprotokollierung in der parse Funktion des Modells hinzugefügt. Seltsamerweise ist jeder von diesen undefined ... Bedeutet das, dass Backbone.js meine Antwort JSON nicht parsen kann?

Edit 2: Vor ein paar Tagen fand ich, dass Problem zu jeder Anforderung tatsächlich eine benutzerdefinierte Header, dass ich das Hinzufügen, war HTTP Basic-Authentifizierung zu ermöglichen. Einzelheiten finden Sie unter this answer.

+0

Ihr Code sieht gut aus (außer, dass Sie 'Model.urlRoot' statt' Model.url' verwenden sollten, aber das ist nicht das Problem hier). Frühere Überarbeitungen Ihres Codes hatten Probleme, aber sind Sie absolut sicher, dass der genaue Code in Ihrer aktuellen Bearbeitung immer noch fehlschlägt? – jevakallio

Antwort

3

haben Ich habe das Problem herausgefunden, obwohl es mir immer noch nicht klar ist, warum es ist, warum es überhaupt ein Problem ist. Die von mir erstellte Webanwendung verfügt über einen Authentifizierungsprozess, bei dem ein HTTP-Basisauthentifizierungsheader mit allen Anforderungen übergeben werden muss.

Um dies mit Backbone arbeiten zu lassen, überging ich die Backbone.sync-Funktion und änderte line 1398, um die Kopfzeile hinzuzufügen.

Originalcode:

var params = {type: type, dataType: 'json'}; 

Modified Code:

var params = { 
    type: type, 
    dataType: 'json', 
    headers: { 
     'Authorization': getAuthHash() 
    } 
}; 

Die Funktion getAuthHash() gibt nur eine Base64 Zeichenfolge, die die entsprechenden Authentifizierungsinformationen darstellen.

Aus irgendeinem Grund führt das Hinzufügen dieses Headers dazu, dass die Synchronisierungs-/Speicherfunktionen fehlschlagen. Wenn ich es herausnehme, funktioniert alles so, wie Sie es erwarten können.

Das Kopfgeld ist noch offen, und ich werde es gerne an jeden belohnen, der erklären kann, warum dies ist, und auch eine Lösung für das Problem bieten.

Edit:

Es sieht aus wie das Problem der Art und Weise war, dass ich den Header der Anforderung Zugabe wurde. Es gibt eine nette kleine JavaScript-Bibliothek available on Github, die dieses Problem löst, indem Sie den HTTP Basic Auth-Header korrekt hinzufügen.

3

Dieser Code:

u.save(); 
console.log(u.id); 
console.log(u.username); 
console.log(u.token); 
console.log(u.created); 

Läuft sofort ... nach, dass es nichts zu laufen und die Warteschlange Ajax-Anforderung beginnt. Die Antwort kommt dann etwas später und nur an diesem Punkt haben sich die Werte geändert.

Es scheint auch, dass diese Eigenschaften nicht direkt auf das Objekt, aber die asynchrone Verarbeitung der in sparen hält nach wie vor, dass Sie würde nicht einmal die erwarteten Ergebnisse erhalten, wenn Sie diesen Code korrigiert console.log(u.get("id")) usw.

+0

Ihr Vorschlag, u.get ("id") anstelle von u.id zu verwenden, macht viel Sinn, aber selbst wenn ich versuche, diese Eigenschaften in einem Erfolgs-Callback oder im Sync-Ereignis des Modells zu protokollieren, bleiben sie unbestimmt denke, es gibt mehr zu dem Problem. – MusikPolice

+0

Ich habe den Code in der ursprünglichen Frage bearbeitet, um Ihre Vorschläge zu integrieren ... Es funktioniert immer noch nicht, und ich bin am Ende meines Wissens. – MusikPolice

+0

@MusikPolice Wenn Sie eine Syntaxanalysefunktion definiert haben, liegt es in Ihrer Verantwortung, das analysierte Modell aus der Antwort zurückzugeben. Diese Funktion wird verwendet, wenn die Antwort vom Server nicht direkt strukturiert ist, um ein Modell von – Esailija

2

i Code getestet haben, für mich seine Werke in Ordnung.

Siehe hier Demo, jsfiddle.net/yxkUD/

+1

ja, es funktioniert .. –

+0

Sorry, ich habe keine zusätzlichen Details über das Problem zu der Frage hinzugefügt. Weitere Informationen finden Sie [diese Beschreibung] (http://stackoverflow.com/a/15003301/591374) – MusikPolice

Verwandte Themen