diff --git a/_examples/response-writer/write-rest/main.go b/_examples/response-writer/write-rest/main.go
index 5e757827..84d3332a 100644
--- a/_examples/response-writer/write-rest/main.go
+++ b/_examples/response-writer/write-rest/main.go
@@ -4,7 +4,6 @@ import (
"encoding/xml"
"github.com/kataras/iris/v12"
- "github.com/kataras/iris/v12/context"
)
// User example struct for json and msgpack.
@@ -53,6 +52,42 @@ func main() {
ctx.JSON(u)
})
+ // Use Secure field to prevent json hijacking.
+ // It prepends `"while(1),"` to the body when the data is array.
+ app.Get("/json_secure", func(ctx iris.Context) {
+ response := []string{"val1", "val2", "val3"}
+ options := iris.JSON{Indent: "", Secure: true}
+ ctx.JSON(response, options)
+
+ // Will output: while(1);["val1","val2","val3"]
+ })
+
+ // Use ASCII field to generate ASCII-only JSON
+ // with escaped non-ASCII characters.
+ app.Get("/json_ascii", func(ctx iris.Context) {
+ response := iris.Map{"lang": "GO-虹膜", "tag": "
"}
+ options := iris.JSON{Indent: " ", ASCII: true}
+ ctx.JSON(response, options)
+
+ /* Will output:
+ {
+ "lang": "GO-\u8679\u819c",
+ "tag": "\u003cbr\u003e"
+ }
+ */
+ })
+
+ // Do not replace special HTML characters with their unicode entities
+ // using the UnescapeHTML field.
+ app.Get("/json_raw", func(ctx iris.Context) {
+ options := iris.JSON{UnescapeHTML: true}
+ ctx.JSON(iris.Map{
+ "html": "Hello, world!",
+ }, options)
+
+ // Will output: {"html":"Hello, world!"}
+ })
+
// Other content types,
app.Get("/binary", func(ctx iris.Context) {
@@ -69,7 +104,7 @@ func main() {
})
app.Get("/jsonp", func(ctx iris.Context) {
- ctx.JSONP(map[string]string{"hello": "jsonp"}, context.JSONP{Callback: "callbackName"})
+ ctx.JSONP(map[string]string{"hello": "jsonp"}, iris.JSONP{Callback: "callbackName"})
})
app.Get("/xml", func(ctx iris.Context) {
@@ -105,6 +140,8 @@ func main() {
// http://localhost:8080/decode
// http://localhost:8080/encode
+ // http://localhost:8080/json_secure
+ // http://localhost:8080/json_ascii
//
// http://localhost:8080/binary
// http://localhost:8080/text
diff --git a/aliases.go b/aliases.go
index 3be42fd9..26014666 100644
--- a/aliases.go
+++ b/aliases.go
@@ -76,6 +76,10 @@ type (
//
// It is an alias of the `context#JSON` type.
JSON = context.JSON
+ // JSONP the optional settings for JSONP renderer.
+ //
+ // It is an alias of the `context#JSONP` type.
+ JSONP = context.JSONP
// ProtoMarshalOptions is a type alias for protojson.MarshalOptions.
ProtoMarshalOptions = context.ProtoMarshalOptions
// ProtoUnmarshalOptions is a type alias for protojson.UnmarshalOptions.
diff --git a/context/context.go b/context/context.go
index a70907d6..3094b94e 100644
--- a/context/context.go
+++ b/context/context.go
@@ -3097,16 +3097,27 @@ func WriteJSON(writer io.Writer, v interface{}, options JSON, optimize bool) (in
return 0, err
}
+ prependSecure := false
+ if options.Secure {
+ if bytes.HasPrefix(result, jsonArrayPrefix) {
+ if options.Indent == "" {
+ prependSecure = bytes.HasSuffix(result, jsonArraySuffix)
+ } else {
+ prependSecure = bytes.HasSuffix(bytes.TrimRightFunc(result, func(r rune) bool {
+ return r == '\n' || r == '\r'
+ }), jsonArraySuffix)
+ }
+ }
+ }
+
if options.UnescapeHTML {
result = bytes.Replace(result, ltHex, lt, -1)
result = bytes.Replace(result, gtHex, gt, -1)
result = bytes.Replace(result, andHex, and, -1)
}
- if options.Secure {
- if bytes.HasPrefix(result, jsonArrayPrefix) && bytes.HasSuffix(result, jsonArraySuffix) {
- result = append(secureJSONPrefix, result...)
- }
+ if prependSecure {
+ result = append(secureJSONPrefix, result...)
}
if options.ASCII {