1
0
mirror of https://github.com/labstack/echo.git synced 2025-03-25 21:38:56 +02:00

Added JSONP API in Context

Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Will Fitzgerald 2015-07-24 15:28:35 -04:00 committed by Vishal Rana
parent 96e5761b75
commit 9257875cb7
5 changed files with 151 additions and 21 deletions

View File

@ -101,8 +101,8 @@ func (c *Context) Set(key string, val interface{}) {
c.store[key] = val
}
// Bind binds the request body into specified type v. Default binder does it
// based on Content-Type header.
// Bind binds the request body into specified type v. Default binder does it based
// on Content-Type header.
func (c *Context) Bind(i interface{}) error {
return c.echo.binder(c.request, i)
}
@ -121,7 +121,7 @@ func (c *Context) Render(code int, name string, data interface{}) (err error) {
return
}
// HTML formats according to a format specifier and sends text/html response with
// HTML formats according to a format specifier and sends HTML response with
// status code.
func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
@ -132,8 +132,8 @@ func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
return
}
// String formats according to a format specifier and sends text/plain response
// with status code.
// String formats according to a format specifier and sends text response with status
// code.
func (c *Context) String(code int, format string, a ...interface{}) (err error) {
c.response.Header().Set(ContentType, TextPlain)
c.response.WriteHeader(code)
@ -143,7 +143,7 @@ func (c *Context) String(code int, format string, a ...interface{}) (err error)
return
}
// JSON sends an application/json response with status code.
// JSON sends a JSON response with status code.
func (c *Context) JSON(code int, i interface{}) (err error) {
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
c.response.WriteHeader(code)
@ -153,7 +153,21 @@ func (c *Context) JSON(code int, i interface{}) (err error) {
return
}
// XML sends an application/xml response with status code.
// JSONP sends a JSONP response with status code. It uses `callback` to construct
// the JSONP payload.
func (c *Context) JSONP(code int, callback string, i interface{}) (err error) {
c.response.Header().Set(ContentType, ApplicationJavaScriptCharsetUTF8)
c.response.WriteHeader(code)
c.response.Write([]byte(callback + "("))
if err = json.NewEncoder(c.response).Encode(i); err != nil {
c.response.clear()
} else {
c.response.Write([]byte(");"))
}
return
}
// XML sends an XML response with status code.
func (c *Context) XML(code int, i interface{}) (err error) {
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
c.response.WriteHeader(code)

View File

@ -11,8 +11,9 @@ import (
"strings"
"encoding/xml"
"github.com/stretchr/testify/assert"
"net/url"
"github.com/stretchr/testify/assert"
)
type (
@ -94,7 +95,19 @@ func TestContext(t *testing.T) {
if assert.NoError(t, err) {
assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, ApplicationJSONCharsetUTF8, rec.Header().Get(ContentType))
assert.Equal(t, userJSON, strings.TrimSpace(rec.Body.String()))
assert.Equal(t, userJSON+"\n", rec.Body.String())
}
// JSONP
req.Header.Set(Accept, ApplicationJavaScript)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
callback := "callback"
err = c.JSONP(http.StatusOK, callback, user{"1", "Joe"})
if assert.NoError(t, err) {
assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, ApplicationJavaScriptCharsetUTF8, rec.Header().Get(ContentType))
assert.Equal(t, callback+"("+userJSON+"\n);", rec.Body.String())
}
// XML

View File

@ -93,6 +93,8 @@ const (
ApplicationJSON = "application/json"
ApplicationJSONCharsetUTF8 = ApplicationJSON + "; " + CharsetUTF8
ApplicationJavaScript = "application/javascript"
ApplicationJavaScriptCharsetUTF8 = ApplicationJavaScript + "; " + CharsetUTF8
ApplicationXML = "application/xml"
ApplicationXMLCharsetUTF8 = ApplicationXML + "; " + CharsetUTF8
ApplicationForm = "application/x-www-form-urlencoded"

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<title>JSONP example</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
var host_prefix = 'http://localhost:3999';
$(document).ready(function() {
// JSONP version - add 'callback=?' to the URL - fetch the JSONP response to the request
$("#jsonp-button").click(function(e) {
e.preventDefault();
// The only difference on the client end is the addition of 'callback=?' to the URL
var url = host_prefix + '/jsonp?callback=?';
$.getJSON(url, function(jsonp) {
console.log(jsonp);
$("#jsonp-response").html(JSON.stringify(jsonp, null, 2));
});
});
});
</script>
</head>
<body>
<div class="container">
<h1>JSONP Example</h1>
JSONP is a method that allows cross-domain server calls. You can read more about
it at the <a href="http://json-jsonp-tutorial.craic.com/index.html">JSON versus JSONP Tutorial</a>.
To see this live, run the server locally and open <a href="http://localhost:3999/index.html">http://localhost:3999/index.html</a> (That is, this page.)
<p>
Server:
<pre>
e.Get("/jsonp", func(c *echo.Context) error {
callback := c.Query("callback")
var content struct {
Response string `json:"response"`
Timestamp time.Time `json:"timestamp"`
Random int `json:"random"`
}
content.Response = "Sent via JSONP"
content.Timestamp = time.Now().UTC()
content.Random = rand.Intn(1000)
return c.JSONP(http.StatusOK, callback, &content)
})
</pre>
</p>
<p>
Client:
<pre>
var url = host_prefix + <span class="highlight">'/jsonp?callback=?';</span>
$.getJSON(url, function(jsonp){
$("#jsonp-response").html(JSON.stringify(jsonp, null, 2));
});
</pre>
<input type="button" class="btn btn-primary btn-lg" id="jsonp-button" value="Get JSONP response">
<pre id='jsonp-response'></pre>
</p>
</div>
</body>
</html>

31
recipes/jsonp/server.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"math/rand"
"net/http"
"time"
"github.com/labstack/echo"
)
func main() {
// Setup
e := echo.New()
e.ServeDir("/", "public")
e.Get("/jsonp", func(c *echo.Context) error {
callback := c.Query("callback")
var content struct {
Response string `json:"response"`
Timestamp time.Time `json:"timestamp"`
Random int `json:"random"`
}
content.Response = "Sent via JSONP"
content.Timestamp = time.Now().UTC()
content.Random = rand.Intn(1000)
return c.JSONP(http.StatusOK, callback, &content)
})
// Start server
e.Run(":3999")
}