Merge a14cf7c08dc37b7f9308248928aa3b16307f3c2f into 2a794cd0b0faa7d829291375b27a3467ea972b0d

This commit is contained in:
Name 2025-12-04 11:31:26 +08:00 committed by GitHub
commit bfebfde599
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 19 deletions

View File

@ -1173,13 +1173,10 @@ func (c *Context) SecureJSON(code int, obj any) {
// JSONP serializes the given struct as JSON into the response body. // JSONP serializes the given struct as JSON into the response body.
// It adds padding to response body to request data from a server residing in a different domain than the client. // It adds padding to response body to request data from a server residing in a different domain than the client.
// It also sets the Content-Type as "application/javascript". // It also sets the Content-Type as "application/javascript".
//
// When the callback parameter is empty, it behaves equivalently to Context.JSON.
func (c *Context) JSONP(code int, obj any) { func (c *Context) JSONP(code int, obj any) {
callback := c.DefaultQuery("callback", "") c.Render(code, render.JsonpJSON{Callback: c.Query("callback"), Data: obj})
if callback == "" {
c.Render(code, render.JSON{Data: obj})
return
}
c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
} }
// JSON serializes the given struct as JSON into the response body. // JSON serializes the given struct as JSON into the response body.

View File

@ -115,14 +115,14 @@ func (r SecureJSON) WriteContentType(w http.ResponseWriter) {
// Render (JsonpJSON) marshals the given interface object and writes it and its callback with custom ContentType. // Render (JsonpJSON) marshals the given interface object and writes it and its callback with custom ContentType.
func (r JsonpJSON) Render(w http.ResponseWriter) (err error) { func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
r.WriteContentType(w) if r.Callback == "" {
ret, err := json.API.Marshal(r.Data) return WriteJSON(w, r.Data)
if err != nil {
return err
} }
if r.Callback == "" { r.WriteContentType(w)
_, err = w.Write(ret)
ret, err := json.API.Marshal(r.Data)
if err != nil {
return err return err
} }

View File

@ -183,19 +183,28 @@ func TestRenderJsonpJSONError(t *testing.T) {
assert.Equal(t, `write "`+`);`+`" error`, err.Error()) assert.Equal(t, `write "`+`);`+`" error`, err.Error())
} }
func TestRenderJsonpJSONError2(t *testing.T) { func TestRenderJsonpJSONWithEmptyCallback(t *testing.T) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
data := map[string]any{ data := map[string]any{
"foo": "bar", "foo": "bar",
"num": 42,
"nested": map[string]any{
"key": "value",
},
} }
(JsonpJSON{"", data}).WriteContentType(w)
assert.Equal(t, "application/javascript; charset=utf-8", w.Header().Get("Content-Type"))
e := (JsonpJSON{"", data}).Render(w) err := (JsonpJSON{Callback: "", Data: data}).Render(w)
require.NoError(t, e)
assert.JSONEq(t, "{\"foo\":\"bar\"}", w.Body.String()) require.NoError(t, err)
assert.Equal(t, "application/javascript; charset=utf-8", w.Header().Get("Content-Type"))
// Verify Content-Type is set to jsonContentType when callback is empty
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
renderData, err := json.API.Marshal(data)
require.NoError(t, err)
// Verify body contains correct JSON data
assert.JSONEq(t, string(renderData), w.Body.String())
} }
func TestRenderJsonpJSONFail(t *testing.T) { func TestRenderJsonpJSONFail(t *testing.T) {