2017-06-05 1 views
0

Ich bin neu in Express und Probleme beim Senden von Daten vom Back-End zum Front-End. Hier ist, was ich tun möchte: Ich habe eine Google Map API auf der Homepage (home.ejs). app.js ist der Server-Code: Wenn die Homepage geladen wird, app.js einige zufällige Standorte generieren und an home.ejs senden, so home.ejs diese Orte als Marker verwenden. Nun möchte ich jedem dieser Marker einen Ereignis-Listener hinzufügen, so dass er, wenn sich die Maus über dem Marker befindet, eine GET-Anfrage an den Server sendet, um ein Bild zum Anzeigen anzufordern.Express-Routing-Trigger: "Nach dem Senden können keine Header festgelegt werden." Fehler

Ich fühle es eine große Herausforderung für mich, die Anfrage/Daten hin und her zu senden. Wenn die Maus vorbei ist, sendet die home.ejs eine GET-Anforderung an /getImage/:num Route, und app.get("/getImage/:num", function(req, res){}) reagiert auf diese Anforderung durch Abrufen der Image-URL, und umleiten an "/" und sendet die URL an es. Dies ist, wo ich die "Can't set headers after they are sent" bekommen.

ich so bin neu Express und EJS, die ich weiß nicht einmal, ob ich auf dem richtigen Weg bin. Wie soll ich dies implementieren, um die Kommunikation durch?

zu erhalten

Dies ist der app.js Server-Datei

var express = require("express"); 
var app = express(); 
//app.use(express.static(__dirname + "/public")); 
app.use(express.static(__dirname)); 
app.set("view engine","ejs"); 

var lng_min = -84.161; 
var lng_max = -83.688; 
var lat_min = 35.849; 
var lat_max = 36.067; 

var urls = [ 
    "http://cdn1-www.dogtime.com/assets/uploads/2015/01/file_21032_the-most-popular-dog-and-cat-names.jpg", 
    "http://qltyctrl.com/wp-content/uploads/2014/03/Sad-Dog-and-Cat.jpg", 
    "https://blog-photos.dogvacay.com/blog/wp-content/uploads/2015/07/dog-cat-smarter-ftr.jpg", 
    "http://qltyctrl.com/wp-content/uploads/2014/03/Dog-and-Cat-on-a-Log.jpg", 
    "http://images.boomsbeat.com/data/images/full/31730/cat-and-dog_1-jpg.jpg", 
    "http://www.vetlocator.com/dailypaws/wp-content/uploads/2012/04/dog-cat2.jpg", 
    "http://qltyctrl.com/wp-content/uploads/2014/03/Old-Dog-and-Cat-Sleepy-Embrace.jpg", 
    "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQXNMdvNfc3WYMqbPrJrnjgHJRp2zB1y9vx545LfO-_U5_yvgBo", 
    "http://www.vetlocator.com/dailypaws/wp-content/uploads/2012/04/dog-cat8.jpg", 
    "http://www.maddiesfund.org/assets/metaImage/robust-dog-cat-foster.jpg" 
] 

var numLocations = 10; 
var data = []; 

function generateData() { 
    // generate random locations and the url to download pictures 
    for (var i = 0; i < numLocations; ++i) { 
     var lng = Math.random() * (lng_max - lng_min) + lng_min; 
     var lat = Math.random() * (lat_max - lat_min) + lat_min; 
     var tuple = { 
      id: i, 
      lng: lng, 
      lat: lat, 
      pic: urls[i] 
     }; 
     data.push(tuple); 
    } 
} 

app.get("/", function(req, res) { 
    //res.send("Hello it works"); 
    data = []; 
    generateData(); 
    res.render("home.ejs", {data: data}); 
}); 

app.get("/getImg/:num", function(req, res) { 
    console.log(req.params.num); 
    var i = Number(req.params.num); 
    res.redirect("/"); 
    res.send({imgUrl: data[i].pic}); 
}); 


app.listen(process.env.PORT, process.env.IP, function() { 
    console.log("Server Started!"); 
}); 

home.ejs Datei:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Demo</title> 
    <link rel="stylesheet" type="text/css" href="/public/app.css"> 

</head> 
<body> 
    <div id="map"> 
    </div> 

    <script> 
     var data = <%- JSON.stringify(data) %>; 
     console.log(data.length); 
     function initMap() { 
     var loc = {lat: 35.9606, lng: -83.9207}; 
     var map = new google.maps.Map(document.getElementById('map'), { 
      zoom: 10, 
      center: loc 
     }); 
     for (var i = 0; i < data.length; ++i) { 
      var loc = {lat: data[i].lat, lng: data[i].lng}; 
      var marker = new google.maps.Marker({ 
        position: loc, 
        map: map 
        // id: i 
      }); 

      var infowindow = new google.maps.InfoWindow(); 
      google.maps.event.addListener(marker, 'mouseover', (function(marker) { 
      return function() { 
        // var content = '<div id="imgDisplay">' 
        //     + '<img src="http://www.maddiesfund.org/assets/metaImage/robust-dog-cat-foster.jpg">' 
        //     + '</div>'; 
        // infowindow.setContent(content); 
        // infowindow.open(map, marker); 


       var xhr = new XMLHttpRequest(); 
       var params = 3; 
       xhr.open('GET','/getImg/'+params, true); 
        xhr.onreadystatechange = function() { 
        if (xhr.readyState == 4 && xhr.status == 200) { 
         console.log(responseText); 
       } 
        } 
      //xhr.send(params); 
      xhr.send(); 


      } 
     })(marker)); 


     } 
     } 
    </script> 

    <script async defer 
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAOwfkV_GbUXyH2s8iD0gS6pje9J3R96dM&callback=initMap"> 
    </script> 

</body> 
</html> 
+0

Ich verstehe nicht, was Sie meinen "app.js reagiert auf diese Anfrage durch Abrufen der Bild-URL, und umleiten zu" "/" 'und sendet die URL an sie." Nachdem ich das gelesen habe, verstehe ich nicht genau, was Sie wollen. Sie können entweder mit 'redirect' auf einen anderen Pfad umleiten, der eine' 3xx' HTTP-Antwort sendet (an diesem Punkt wird der Handler für diesen Pfad ausgeführt) * oder * Sie können Daten mit 'send' senden, die eine' 2xx' Antwort senden. Diese schließen sich gegenseitig aus - entweder ist die Antwort eine Umleitungsantwort oder eine Datenantwort. Soll die Top-Level-Seite nach einer Anfrage an '/ getImg' auf'/'umgeleitet werden? – apsillers

+0

Sorry wegen der Verwirrung. Die Google Map befindet sich auf der Startseite ("/"). Wenn ich die GET-Anfrage sende, wird sie an "/ getImg /: num" gesendet. Appget ("/ getImg /: num",) antwortet auf diese GET-Anfrage und holt die Bild-URL aus der Datenmatrix, aber ich möchte, dass sie auf "/" umleitet, damit ich das Bild auf der Homepage anzeigen kann ("/") – daydayup

+0

Okay, ich denke, die Antwort hier ist: Ihr Verständnis von was Redirect ("/") tut ist falsch. 'redirect ("/")' sendet eine '3xx' (wahrscheinlich' 301' oder '302') HTTP-Antwort und sagt:" Ich habe keine Antwort für Sie; versuchen Sie stattdessen, Daten aus dem Pfad '/' zu laden . " Aber Sie wollen das nicht tun - Sie haben bereits die Daten und sind bereit, es zu senden! Stattdessen denke ich, dass Sie die URL aus dem 'urls'-Array senden möchten, und dann auf der Client-Seite' img = new Image(); img.src = Antworttext; document.body.appendChild (img) '. Ist das richtig? – apsillers

Antwort

1

Sie den Zweck dermißverstehen. Express redirect Funktion sagt, "Dieser Pfad hat keine Antwort; stattdessen versuchen, eine Anfrage an diesen anderen Pfad senden und sehen, was es sagt." (Dies wird durch eine 3xx Antwort wie 301 oder 302 getan.)

Ihre Verwirrung ist, dass Sie denken, Sie müssen den Client sagen, welche Seite sollte die angegebene URL machen. Aber das ist nicht notwendig: Der Server teilt dem Client nicht mit, wie die von ihm gesendeten Daten rendern kann. Der Server sendet nur Daten, und der Client entscheidet, was damit zu tun ist.

Die gute Nachricht ist, dass Ihr clientseitiges JavaScript seine Aufgabe korrekt erfüllt. Es verwendet eine XMLHttpRequest, um Daten vom Server abzurufen. Lassen Sie den Server diese Daten einfach mit der send-Funktion senden und nicht rufen Sie redirect. Sobald Ihre Client-Seite die URL zu laden, können Sie es in einem <img> Elemente laden mit

var img = new Image(); 
img.src=responseText; 
document.body.appendChild(img); 

in Ihrem onreadystatechange Zuhörer. Sie können document.getElementById(...) verwenden, um ein anderes Element zu erhalten, wenn Sie das Element nicht zu Ihrem body hinzufügen möchten.

+0

Vielen Dank für die Hilfe und erklären das Konzept für mich !!! Ich habe es gerade funktioniert. – daydayup

Verwandte Themen