我試圖從Go web服務器下載壓縮文件。我已經成功將文件壓縮並可以從我的服務器目錄中解壓縮。我遇到的問題是提供文件並使用Javascript下載。從golang服務器下載瀏覽器中的壓縮文件
這裏是我的代碼的概述:
1)請對服務器的請求,從另一個端點
2檢索數據)結構基於文件類型用戶希望返回的數據(CSV( setupCSVRows功能)或JSON)
3)而寫緩衝區的字節到文件,並返回該文件的地址
4)當用戶點擊一個鏈接,使一個HTTP GET與文件地址的請求,並在新打開的內容窗戶向下負載
每次我嘗試解壓縮我得到了錯誤的文件:歸檔文件不完整(與該取檔節目)和Mac上的默認歸檔實用程序然後顯示一個簡短的加載屏幕關閉。
Go代碼:
func ExportData(writer http.ResponseWriter, req *http.Request, session sessions.Session) (int, string) {
headers := HeaderCreation{
OriginalRequest: req,
Session: session,
}
qs := req.URL.Query()
if len(qs["collectionID"]) != 1 {
return 400, "ERROR: Must submit one collectionID in query string"
}
if len(qs["fileType"]) != 1 {
return 400, "ERROR: Must submit one fileType in query string"
}
collID := qs["collectionID"][0]
fileType := qs["fileType"][0]
url := "http://" + config.Data.Address + "/api/" + collID
response, err := httpClient.DoSystemRequest("GET", url, nil, headers)
if err != nil {
return 500, "ERROR: Could not resolve DataURL/api" + err.Error()
} else {
contents, err := ioutil.ReadAll(response.Body)
response.Body.Close()
if err != nil {
return 400, "ERROR: Response from Platform unreadable"
}
buf := new(bytes.Buffer)
w := zip.NewWriter(buf)
file, err := w.Create(collID + "." + fileType)
if err != nil {
return 400, "ERROR: Unable to create zip file with name of: " + collID + " and type of: " + fileType + "; " + err.Error()
}
switch fileType {
case "csv":
rows, err := setupCSVRows(contents)
if err != nil {
return 400, err.Error()
}
_, err = file.Write(rows)
if err != nil {
return 400, "Unable to write CSV to zip file; " + err.Error()
}
case "json":
_, err := file.Write(contents)
if err != nil {
return 400, err.Error()
}
} // end switch
err = w.Close()
if err != nil {
return 400, "ERROR: Unable to close zip file writer; " + err.Error()
}
//create fileName based on collectionID and current time
fileAddress := collID + strconv.FormatInt(time.Now().Unix(), 10)
//write the zipped file to the disk
ioutil.WriteFile(fileAddress + ".zip", buf.Bytes(), 0777)
return 200, fileAddress
} //end else
}
func ReturnFile(writer http.ResponseWriter, req *http.Request) {
queries := req.URL.Query()
fullFileName := queries["fullFileName"][0]
http.ServeFile(writer, req, fullFileName)
//delete file from server once it has been served
//defer os.Remove(fullFileName)
}
func setupCSVRows(contents []byte) ([]byte, error) {
//unmarshal into interface because we don't know json structure in advance
var collArr interface{}
jsonErr := json.Unmarshal(contents, &collArr)
if jsonErr != nil {
return nil, errors.New("ERROR: Unable to parse JSON")
}
//had to do some weird stuff here, not sure if it's the best method
s := reflect.ValueOf(collArr)
var rows bytes.Buffer
var headers []string
for i := 0; i < s.Len(); i++ {
var row []string
m := s.Index(i).Interface()
m2 := m.(map[string]interface{})
for k, v := range m2 {
if i == 0 {
if k != "item_id" {
headers = append(headers, k)
}
}
if k != "item_id" {
row = append(row, v.(string))
}
}
if i == 0 {
headersString := strings.Join(headers, ",")
rows.WriteString(headersString + "\n")
}
rowsString := strings.Join(row, ",")
rows.WriteString(rowsString + "\n")
}
return rows.Bytes(), nil
}
JavaScript代碼:
$scope.exportCollection = function(fileType) {
$scope.exporting = true;
$scope.complete = false;
$http.get('/api/batch/export?collectionID=' + $scope.currentCollection.collectionID + '&fileType=' + fileType.toLowerCase()).success(function(data){
$scope.fileAddress = data;
}).error(function(err) {
console.log(err);
});
};
$scope.downloadFile = function() {
$http.get('/api/batch/export/files?fullFileName=' + $scope.fileAddress + ".zip")
.success(function(data) {
console.log(data);
//window.open("data:application/zip;base64," + content);
//var content = "data:text/plain;charset=x-user-defined," + data;
var content = "data:application/zip;charset=utf-8," + data;
//var content = "data:application/octet-stream;charset=utf-8" + data;
//var content = "data:application/x-zip-compressed;base64," + data;
//var content = "data:application/x-zip;charset=utf-8," + data;
// var content = "data:application/x-zip-compressed;base64," + data;
window.open(content);
})
.error(function(err) {
console.log(err);
})
}
正如你所看到的,我已經嘗試了許多不同的URI方案用於下載該文件,但沒有奏效。
我需要在服務器端設置MIME類型嗎?
任何幫助將不勝感激。請讓我知道,如果我需要包括任何更多的細節。
是否使用JS中的'+'操作符強制轉換爲字符串? –