Скачайте * .csv с моего сервера - PullRequest
0 голосов
/ 30 апреля 2018

Я новичок в Golang, и сейчас я пишу небольшое приложение, которое анализирует некоторые страницы. Я получил индексную страницу:

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

Таким образом, после нажатия кнопки «Отправить» он переходит на страницу анализа (используя tebeca / selenium pkg) и в конце записывает данные в файл result.csv, как

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)
    }
}

И в итоге я получил файл result.csv в /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)
}

Итак, главный вопрос: Есть ли способ получить ссылку для загрузки result.csv на мой жесткий диск? Реализация не важна. Может быть в конце writeToCSV () , когда result.csv будет готов, появится окно, в котором вы можете выбрать место для сохранения файла, или после получения result.csv появится какая-нибудь ссылка типа «Нажмите, чтобы скачать». после нажатия появляется окно загрузки и т. д.

Я застрял и действительно не знаю, как реализовать загрузку. Буду благодарен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

На вашем сервере 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) {
    ...
    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) 
  }

В вашем клиенте

Поскольку загружаемый файл будет отправлен сервером, необходимо использовать функцию js, чтобы сначала отправить форму на сервер. Затем, после получения ответа от сервера, загрузка будет инициирована непосредственно той же функцией.

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> 

В файле js

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));
0 голосов
/ 30 апреля 2018

Golang упрощает обслуживание файлов. Вы можете использовать компонент FileServer в net / http (см. Ниже). Вам просто нужно сохранить файл в папке, которую вы обслуживаете ("/ static" в примере ниже). Таким образом, ваш код должен использовать выделенный путь:

file, err := os.Create("/home/username/static/result.csv")

И с добавлением следующего обработчика FileServer ваш файл будет доступен в http://domain/static/result.csv.

package main

import (
    "net/http"
)

func main() {
...
    fs := http.FileServer(http.Dir("/home/username/static"))
    http.Handle("/static/", http.StripPrefix("/static", fs))
    http.ListenAndServe(":3000", nil)
...
}

Обратите внимание, что все файлы под статическим будут обслуживаться. Для получения дополнительной информации см. документы .

Если вам нужна помощь в написании клиентской части для загрузки файла, см. этот вопрос о стекопереработке .

...