I am new to Golang and now I'm writing small app which parse some page. I got index page:
<form action="/" method='POST'>
Enter credentials:<br>
Login: <input type="text" name="login" >
<br>
Password: <input type="password" name="password" >
<br>
Search link:<br>
<input type="text" name="link" >
<br>
<input type="submit" value="Submit">
</form>
So after clicking Submit button it goes to parse page (using tebeca/selenium pkg), and in the end writes data to result.csv like
func writeToCSV(users []linkedinUser) {
data := users
enc := struct2csv.New()
rows, err := enc.Marshal(data)
if err != nil {
fmt.Printf("ERROR marshaling file, %s", err)
}
file, err := os.Create("result.csv")
if err != nil {
fmt.Printf("ERROR creating file, %s", err)
}
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
for _, value := range rows {
err := writer.Write(value)
if err != nil {
fmt.Printf("ERROR writing file, %s", err)
}
}
And in the end I got result.csv file in /home/username/go/src/parser/parsertool/src/result.csv
my main.go
func main() {
r := mux.NewRouter()
r.HandleFunc("/", indexHandler)
http.Handle("/", r)
err := http.ListenAndServe(":3000", nil) // setting listening port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("./front/index.html")
badLoginT, _ := template.ParseFiles("./front/error.html")
r.ParseForm()
login := r.PostFormValue("login")
password := r.PostFormValue("password")
link := r.PostFormValue("link")
if login != "" || password != "" {
userCred := logincredentials.SetCredentials(login, password)
if logincredentials.CheckCredentials(userCred) && link != "" {
crawler.Crawl(link, login, password)
} else {
badLoginT.Execute(w, nil)
}
}
t.Execute(w, nil)
}
So the main question: is there a way to get a link to download result.csv to my hard drive? The implementation isn`t important. May be in the end of writeToCSV() when result.csv is ready, window where you could choose where to save file will appear, or after getting result.csv, some link like "Click to download" will appear and after clicking you can see download window etc.
I'm stuck and really don't have any idea how to implement downloading. I would be grateful for any help.
On your Go server
func main() {
r := mux.NewRouter()
r.HandleFunc("/", indexHandler)
http.Handle("/", r)
err := http.ListenAndServe(":3000", nil) // setting listening port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
...
Openfile, err := os.Open(Filename)
FileSize := strconv.FormatInt(FileStat.Size(), 10)
FileContentType := http.DetectContentType(FileHeader)
//Send the headers before sending the file
writer.Header().Set("Content-Disposition", "attachment; filename="+Filename)
writer.Header().Set("Content-Type", FileContentType)
writer.Header().Set("Content-Length", FileSize)
//Send the file
io.Copy(w, Openfile)
}
In your client
Since the file to be downloaded will be sent by the server, one need to use a js function to post the form first to the server. Then after receiving the response of the server, the download will be triggered directly by the same function.
html
<form>
Enter credentials:<br>
Login: <input id="login" type="text" name="login" >
<br>
Password: <input id="password" type="password" name="password" >
<br>
Search link:<br>
<input id="link" type="text" name="link" >
<br>
<input type="button" onclick="downloadFile()">
</form>
In a js file
function downloadFile() {
var data = {
login: document.querySelector('#login').value,
password: document.querySelector('#password').value,
link: document.querySelector('#link').value
}
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
var a;
if (xhttp.readyState === 4 && xhttp.status === 200) {
a = document.createElement('a');
a.href = window.URL.createObjectURL(xhttp.response);
// Give to file the name you wish
a.download = "test-file.xls";
a.style.display = 'none';
document.body.appendChild(a);
a.click();
}
}
}
xhttp.open("POST", urlserver);
xhttp.setRequestHeader("Content-Type", "application/json");
// set responseType as blob for binary responses
xhttp.responseType = 'blob';
xhttp.send(JSON.stringify(data));