2017-04-09 2 views
2

zurückschicken Ich schrieb einen einfachen Web-Server, der den Inhalt einer bestimmten URL erhält und schreibt es mit einem http.ResponseWriter. Das Problem ist jedoch, dass auf der Seite keine Bilder und CSS angezeigt werden. Der Code ist unten angegeben:Ein Web-Server, der den Inhalt der angegebenen URL

func factHandler(w http.ResponseWriter, r *http.Request) { 
    res, err := http.Get("http://www.meaningfultype.com/") 
    if err != nil { 
     log.Fatal(err) 
    } 
    robots, err := ioutil.ReadAll(res.Body) 

    res.Body.Close() 
    if err != nil { 
     log.Fatal(err) 
    } 
    w.Write(robots) 
} 

Was muss ich ändern, so dass die die gesamte Seite, wie im Web-Browser zurückgegeben wird, gesehen?

Antwort

0

TL; DR

  • Sie werden nur dazu dienen, die Root-HTML-Seite, müssen Sie auch auf Anfragen zu anderen Ressourcen reagieren (Sie können Sehen Sie, welche Ressource mit der URL-Variablen der * http.Request-Variable angefordert wird.

  • Wenn Sie die Ressourcen bereitstellen, müssen Sie die Headers schreiben Content-Type der Browser wissen zu lassen, was die Art der Ressource ist (wie image/png)

Voll Antwort

Was Sie in Ihrer Anfrage-Handler tun http://www.meaningfultype.com/ wird immer, die HTML-Seite, dann wird der Browser eine findet Bild wie /images/header-logo.png und macht die Anfrage, es zu bekommen, aber Ihr Server in localhost weiß nicht, wie man auf http://localhost/images/header-logo.png reagiert.

Angenommen, Ihre Handler Funktionsanforderungen an die Wurzel des Servers ("/") ist der Umgang, könnten Sie die angeforderte URL r.URL bekommen und es verwenden, um die erforderliche Ressource zu erhalten:

url := "http://www.meaningfultype.com/" 
if r.URL.Host == "" { 
    url += r.URL.String() 
} else { 
    url = r.URL.String() 
} 
res, err := http.Get(url) 

Das Problem ist, dass selbst Danach werden alle Ressourcen als plain/text gesendet, da Sie nicht die des Headers festlegen. Aus diesem Grund müssen Sie vor dem Schreiben den Typ der Ressource angeben.Um zu wissen, was die Art der Ressource ist, ist es nur bekommen vom Content-Type Sie nur in der Kopfzeile der Antwort von http.Get erhalten:

contentType := res.Header.Get("Content-Type") 
w.Header().Set("Content-Type", contentType) 
w.Write(robots) 

Das Endergebnis:

package main 

import (
    "io/ioutil" 
    "log" 
    "net/http" 
) 

func main() { 
    http.HandleFunc("/", factHandler) 
    http.ListenAndServe(":8080", nil) 
} 

func factHandler(w http.ResponseWriter, r *http.Request) { 
    url := "http://www.meaningfultype.com/" 
    if r.URL.Host == "" { 
     url += r.URL.String() 
    } else { 
     url = r.URL.String() 
    } 
    res, err := http.Get(url) 
    if err != nil { 
     log.Fatal(err) 
    } 
    robots, err := ioutil.ReadAll(res.Body) 

    res.Body.Close() 
    if err != nil { 
     log.Fatal(err) 
    } 
    contentType := res.Header.Get("Content-Type") 
    w.Header().Set("Content-Type", contentType) 
    w.Write(robots) 
} 
+0

Dank es funktionierte für mich. –

+0

wie man es verwaltet, wenn url gegeben in dem Beispiel nicht fix.e.g. Ich möchte jede URL im Browser geben wie unten angegeben: http: // localhost: 8080/fastor/ttp: //www.meaningfultype.com/ –

+1

Sie müssen nur die 'url' Variable auf den richtigen Wert setzen. Die Variable "r.URL" enthält die URL, die der Benutzer angefordert hat (in diesem Fall http: // localhost: 8080/fastor/http: //www.meaningfultype.com/). Sie müssen also einfach "http: //" entfernen. localhost: 8080/fastor/'und benutze den Rest des Strings als Wert für' url', aber beachte, dass doppelte Schrägstriche durch einen Schrägstrich ersetzt werden, so dass die URL im Pfad 'http: /www.meaningfultype' wird. com es ist besser, das Schema nicht in den Pfad aufzunehmen und es manuell zur Zeichenkette hinzuzufügen. – raulsntos

2

Das Problem hier ist vermutlich, dass die Website, die Sie verweisen, relative Pfade für die Bilder und Stylesheets verwendet, z. "/css/main.css". Die lokale Website, die Sie mit Ihrem Go-Dienst an den Browser senden, verfügt über eine andere Domäne (z. B. localhost). Daher kann der relative Pfad nicht vom Browser aufgelöst werden (http://localhost/css/main.css).

Sie müssen also entweder eine Basis-URL in dem von Ihnen bereitgestellten Dokument festlegen oder alternativ jeden relativen Pfad in einen absoluten Pfad (/css/main.css bis http://originalwebsite.com/css/main.css) umschreiben.

Zum Hinzufügen des Basis-Tags oder Umschreiben der URLs im Dokument empfehle ich, etwas wie goquery zu verwenden, mit dem Sie die HTML-Struktur ähnlich wie jQuery bearbeiten können.

Beispiel für das Hinzufügen eines <base> tag:

import (
    "github.com/PuerkitoBio/goquery" 
    "fmt" 
) 

func main() { 
    doc,err := goquery.NewDocument("http://www.meaningfultype.com/") 

    if err != nil { 
     panic(err) 
    } 

    m := doc.Find("head") 

    m.Children().First().BeforeHtml(`<base url="http://localhost/">`) 

    fmt.Println(doc.Html()) 
} 
Verwandte Themen