Go HTTP不会为SVG设置头部

huangapple go评论116阅读模式
英文:

Go HTTP will not set header for SVG

问题

我正在生成一个SVG(它将在一个单独的浏览器窗口中加载,检测到头部错误时),将内容类型设置为"image/svg+xml",然后写入SVG,但是当它发送到浏览器时,它以text/xml的形式显示。

我首先写入头部(这是这个问题的问题所在),在几个小时内毫无目的地移动代码后,我已经没有任何想法了。

这是我的代码:

  1. const circlesize = 2.5
  2. // http.HandleFunc("/rendermap.svg", rendermapw)
  3. func rendermapw(w http.ResponseWriter, r *http.Request) {
  4. if r.Method != "GET" {
  5. w.WriteHeader(405)
  6. return
  7. }
  8. fmt.Println("Received request " + r.URL.String())
  9. var mapstring string
  10. // 已经渲染过
  11. if mapcache.valid {
  12. mapstring = mapcache.cache
  13. } else {
  14. // 获取模板
  15. contentb, err := ioutil.ReadFile("src/maptemplate.svg")
  16. if err != nil {
  17. fmt.Println("Error with request:", r)
  18. fmt.Println(err)
  19. w.WriteHeader(500)
  20. return
  21. }
  22. content := strings.Split(string(contentb), "<!--template-->")
  23. // 从数据库中获取数据
  24. alldata := *pullall()
  25. mapstring = content[0] // 头部
  26. for _, e := range alldata {
  27. newcircle := content[1]
  28. // 将uint64转换为字符串(将uint16转换为int64)
  29. newcircle = strings.Replace(newcircle, "{ulat}", strconv.FormatInt(int64(e.Ulat), 10), 1)
  30. newcircle = strings.Replace(newcircle, "{ulon}", strconv.FormatInt(180-int64(e.Ulon), 10), 1)
  31. newcircle = strings.Replace(newcircle, "{size}", strconv.FormatFloat(circlesize, 'f', 4, 64), 1)
  32. mapstring += newcircle
  33. }
  34. mapstring += content[2]
  35. // 保存缓存并发送
  36. mapcache = mapcached{
  37. valid: true,
  38. cache: mapstring,
  39. }
  40. }
  41. // 上面的所有代码都是有效的,我只是为了完整性而贴出来
  42. w.WriteHeader(200)
  43. w.Header().Set("content-type", "image/svg+xml")
  44. _, err := fmt.Fprint(w, mapstring) // 我也尝试过 w.Write([]byte(mapstring))
  45. if err != nil {
  46. fmt.Println("Error with request:", r)
  47. fmt.Println(err)
  48. w.WriteHeader(500)
  49. return
  50. }
  51. }

这是发送到浏览器的内容:

  1. Content-Type: text/xml; charset=utf-8

maptemplate.svg的内容如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  3. <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 360 180" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" fill="#0098ff">
  4. <!--template-->
  5. <circle cx="{ulat}" cy="{ulon}" r="{size}" fill-opacity=".5"/>
  6. <!--template-->
  7. </svg>

如果我删除"<?xml version..."这一行,浏览器将收到text/plain类型的内容。

英文:

I'm generating an SVG (that will load in a separate browser window where it detects that the header is wrong), setting the content-type to &quot;image/svg+xml&quot;, then writing the SVG, but when it is sent to the browser, it comes out as text/xml.

I'm writing the header first (which was the problem in this issue) and I'm out of ideas after moving stuff around aimlessly for a few hours.

Here is my code:

  1. const circlesize = 2.5
  2. // http.HandleFunc(&quot;/rendermap.svg&quot;, rendermapw)
  3. func rendermapw(w http.ResponseWriter, r *http.Request) {
  4. if r.Method != &quot;GET&quot; {
  5. w.WriteHeader(405)
  6. return
  7. }
  8. fmt.Println(&quot;Received request &quot; + r.URL.String())
  9. var mapstring string
  10. // already rendered
  11. if mapcache.valid {
  12. mapstring = mapcache.cache
  13. } else {
  14. // get template
  15. contentb, err := ioutil.ReadFile(&quot;src/maptemplate.svg&quot;)
  16. if err != nil {
  17. fmt.Println(&quot;Error with request:&quot;, r)
  18. fmt.Println(err)
  19. w.WriteHeader(500)
  20. return
  21. }
  22. content := strings.Split(string(contentb), &quot;&lt;!--template--&gt;&quot;)
  23. // pull from database
  24. alldata := *pullall()
  25. mapstring = content[0] // header
  26. for _, e := range alldata {
  27. newcircle := content[1]
  28. // string from uint64 (int64 from uint16)
  29. newcircle = strings.Replace(newcircle, &quot;{ulat}&quot;, strconv.FormatInt(int64(e.Ulat), 10), 1)
  30. newcircle = strings.Replace(newcircle, &quot;{ulon}&quot;, strconv.FormatInt(180-int64(e.Ulon), 10), 1)
  31. newcircle = strings.Replace(newcircle, &quot;{size}&quot;, strconv.FormatFloat(circlesize, &#39;f&#39;, 4, 64), 1)
  32. mapstring += newcircle
  33. }
  34. mapstring += content[2]
  35. // save cache &amp; send
  36. mapcache = mapcached{
  37. valid: true,
  38. cache: mapstring,
  39. }
  40. }
  41. // everything above this works, I&#39;m just posting it for completion&#39;s sake
  42. w.WriteHeader(200)
  43. w.Header().Set(&quot;content-type&quot;, &quot;image/svg+xml&quot;)
  44. _, err := fmt.Fprint(w, mapstring) // I also tried w.Write([]byte(mapstring))
  45. if err != nil {
  46. fmt.Println(&quot;Error with request:&quot;, r)
  47. fmt.Println(err)
  48. w.WriteHeader(500)
  49. return
  50. }
  51. }

This is what gets sent to the browser:

  1. Content-Type: text/xml; charset=utf-8

Here is maptemplate.svg looks like:

  1. &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  2. &lt;!DOCTYPE svg PUBLIC &quot;-//W3C//DTD SVG 1.1//EN&quot; &quot;http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd&quot;&gt;
  3. &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 360 180&quot; fill-rule=&quot;evenodd&quot; stroke-linejoin=&quot;round&quot; stroke-miterlimit=&quot;2&quot; fill=&quot;#0098ff&quot;&gt;
  4. &lt;!--template--&gt;
  5. &lt;circle cx=&quot;{ulat}&quot; cy=&quot;{ulon}&quot; r=&quot;{size}&quot; fill-opacity=&quot;.5&quot;/&gt;
  6. &lt;!--template--&gt;
  7. &lt;/svg&gt;

If I remove the "<?xml version..." line, the browser gets sent text/plain.

答案1

得分: 1

我已经修复了。在w.WriteHeader(200)之前,你必须添加w.Header().Set("content-type", "image/svg+xml")

修复后的代码:

  1. // ...
  2. w.Header().Set("content-type", "image/svg+xml")
  3. w.WriteHeader(200)
  4. _, err := fmt.Fprint(w, mapstring)
  5. if err != nil {
  6. fmt.Println("请求错误:", r)
  7. fmt.Println(err)
  8. w.WriteHeader(500)
  9. return
  10. }
英文:

I fixed it. You have to have w.Header().Set(&quot;content-type&quot;, &quot;image/svg+xml&quot;) before w.WriteHeader(200).

Working code:

  1. // ...
  2. w.Header().Set(&quot;content-type&quot;, &quot;image/svg+xml&quot;)
  3. w.WriteHeader(200)
  4. _, err := fmt.Fprint(w, mapstring)
  5. if err != nil {
  6. fmt.Println(&quot;Error with request:&quot;, r)
  7. fmt.Println(err)
  8. w.WriteHeader(500)
  9. return
  10. }

huangapple
  • 本文由 发表于 2022年3月19日 10:00:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/71534821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定