2017-06-05 72 views
0

我是Express新手,無法將數據從後端發送到前端。這是我想要做的:我在主頁上有一個Google Map API(home.ejs)。 app.js是服務器代碼:當主頁加載時,app.js生成一些隨機位置併發送到home.ejs,因此home.ejs使用這些位置作爲標記。現在我想爲每個這些標記添加一個事件監聽器,這樣當鼠標懸停在標記上時,它會向服務器發送一個GET請求,以請求顯示一張圖片。表示路由觸發器:「發送後無法設置標頭。」錯誤

我覺得來回發送請求/數據是一個很大的挑戰。當鼠標結束時,home.ejs發送GET請求到/getImage/:num路由,並且app.get("/getImage/:num", function(req, res){})通過檢索圖像url來響應該請求,並重定向到"/",並將URL發送給它。這是我得到的「Can't set headers after they are sent"

我很新的表達與EJS,我甚至不知道我是否在正確的軌道上。我應該如何實現這個經過?

獲得通信

這是app.js服務器文件

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文件:

<!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

我不明白你的意思,「app.js通過檢索圖片url來響應該請求,並重定向到」/「'並將url發送給它。」讀完這些後,我不明白你想要發生什麼。你可以使用'redirect'重定向到另一個路徑,'redirect'發送一個'3xx' HTTP響應(此時該路徑的處理程序將運行)*或*可以通過發送'2xx'響應的'send'發送數據。這些是互斥的 - 要麼是響應是重定向響應還是數據響應。在請求到/ getImg後,你想讓頂層頁面重定向到'/'嗎? – apsillers

+0

對此感到抱歉。 Google地圖位於首頁(「/」)。當我發送GET請求時,它被髮送到「/ getImg /:num」。應用程序。get(「/ getImg /:num」)響應GET請求並從數據矩陣中提取圖像URL,但我希望它重定向到「/」,以便我可以在主頁上顯示圖像(「/」) – daydayup

+0

好的,我認爲這裏的答案是:你對'重定向(「/」)做什麼的理解是錯誤的。 'redirect(「/」)'發送一個'3xx'(可能是'301'或'302')HTTP響應並且說:「我沒有給你答案;相反,嘗試從路徑加載數據'/' 「。但是你不想這麼做 - 你已經有了這些數據並準備發送它!相反,我想你要做的就是從'urls'數組發送URL,然後在客戶端執行'img = new Image(); img.src = responseText的; document.body.appendChild(IMG)'。是對的嗎? – apsillers

回答

1

你誤解的0123宗旨。 Express的redirect函數說:「這條路徑沒有答案,而是嘗試向其他路徑發送請求,看看它說了什麼。」 (這是通過3xx響應完成的,如301302。)

您的困惑是,您認爲您需要告訴客戶端哪個頁面應呈現給定的URL。但這不是必需的:服務器不會告訴客戶端如何呈現它發送的數據。服務器只是發送數據,客戶端決定如何處理它。

好消息是您的客戶端JavaScript正在正確地完成其工作。它使用XMLHttpRequest從服務器獲取數據。只需要服務器實際發送該數據與send函數和不要調用redirect。一旦您的客戶端有要加載的URL,您可以在<img>元素與

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

onreadystatechange監聽器里加載它。如果您不想將元​​素添加到您的body,則可以使用document.getElementById(...) 獲取不同的元素。

+0

非常感謝你的幫助,並向我解釋了這個概念!我剛剛得到它的工作。 – daydayup

相關問題