Edit: Since this writing, rs/cors has been identified as the easiest and best way to do CORS in Go.

/*
 * Boilerplate for handling CORS preflighted requests.
 * https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests
 */
package main

import (
	"fmt"
	"log"
	"net/http"
	"strings"
)

// Define length of time results of preflight
// can be cached
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Access-Control-Max-Age
var MaxAge = "60"

// Define all allowed methods here.
var AllowedMethods = map[string]bool{
	"GET":  true,
	"POST": true,
}

// Define all allowed headers here.
var AllowedHeaders = map[string]bool{
	"XPING": true,
}

// Define all allowed origins here.
// Can be wildcard ("*") or exactly ONE URI (e.g. "www.nhatqbui.com")
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
var AllowedOrigins = "*"

func getKeys(m map[string]bool) []string {
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	return keys
}

// Example method handling preflight requests and normal requests.
func handleAjaxHello(w http.ResponseWriter, r *http.Request) {
	if r.Method == "OPTIONS" {
		// Handle pre-flight here.
		// Note: We begin by manually checking the headers of the preflight.
		//       We can actually respond with the information communicated
		//       in the response headers and the browser should handle
		//       whether the subsequent is carried out. Here, we are being
		//       very explicit and checking the headers ourselves.

		// Pre-flight will indicate the method of the actual request.
		// Check that the method is a member of the set of allowed methods.
		reqMethod, ok := r.Header["Access-Control-Request-Method"]
		if !ok {
			// Handle unspecified methods here
			// In this example, we don't do anything and return.
			return
		}

		hasMethod := false
		for _, method := range reqMethod {
			if AllowedMethods[method] {
				hasMethod = true
				break
			}
		}
		if !hasMethod {
			// Handle incorrect methods here
			// In this example, we don't do anything and return.
			return
		}

		// Check that subsequent request will have appropriate headers.
		// This one is more nuanced. You should consider:
		//   - should the request contain ALL allowed headers?
		//   - or should the request headers be allowed headers
		//     (but not necessarily containing all allowed headers)
		// Here, we just check that the request headers are allowed headers.
		// Whether it has-all-necessary-headers is not checked.
		reqHeaders, ok := r.Header["Access-Control-Request-Headers"]
		if !ok {
			// Handle unspecified methods here.
			// In this example, we don't do anything and return.
			return
		}
		for _, headers := range reqHeaders {
			for _, header := range strings.Split(headers, ",") {
				if !AllowedHeaders[header] {
					// Handle incorrect headers here
					// In this example, we don't do anything and return.
					return
				}
			}
		}

		// We arrived here, the preflight has passed our checks
		// And the subsequent request will be valid.
		w.Header().Set("Access-Control-Allow-Origin", AllowedOrigins)
		w.Header().Set("Access-Control-Allow-Methods", strings.Join(getKeys(AllowedMethods), ","))
		w.Header().Set("Access-Control-Allow-Headers", strings.Join(getKeys(AllowedHeaders), ","))
		w.Header().Set("Access-Control-Max-Age", MaxAge)
	} else if r.Method == "POST" {
		var jsonStr = []byte(fmt.Sprintf(`{"data":"PONG"}`))
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.Write(jsonStr)
	}
}

func main() {
	http.HandleFunc("/ajax/hello", handleAjaxHello)

	err := http.ListenAndServeTLS(":8080", "./certs/testing.crt", "./certs/testing.key", nil)
	if err != nil {
		log.Fatal("ListenAndServer: ", err)
	}
}