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:
parent
96e5761b75
commit
9257875cb7
28
context.go
28
context.go
@ -101,8 +101,8 @@ func (c *Context) Set(key string, val interface{}) {
|
|||||||
c.store[key] = val
|
c.store[key] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind binds the request body into specified type v. Default binder does it
|
// Bind binds the request body into specified type v. Default binder does it based
|
||||||
// based on Content-Type header.
|
// on Content-Type header.
|
||||||
func (c *Context) Bind(i interface{}) error {
|
func (c *Context) Bind(i interface{}) error {
|
||||||
return c.echo.binder(c.request, i)
|
return c.echo.binder(c.request, i)
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ func (c *Context) Render(code int, name string, data interface{}) (err error) {
|
|||||||
return
|
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.
|
// status code.
|
||||||
func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
|
func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
|
||||||
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
||||||
@ -132,8 +132,8 @@ func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// String formats according to a format specifier and sends text/plain response
|
// String formats according to a format specifier and sends text response with status
|
||||||
// with status code.
|
// code.
|
||||||
func (c *Context) String(code int, format string, a ...interface{}) (err error) {
|
func (c *Context) String(code int, format string, a ...interface{}) (err error) {
|
||||||
c.response.Header().Set(ContentType, TextPlain)
|
c.response.Header().Set(ContentType, TextPlain)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
@ -143,7 +143,7 @@ func (c *Context) String(code int, format string, a ...interface{}) (err error)
|
|||||||
return
|
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) {
|
func (c *Context) JSON(code int, i interface{}) (err error) {
|
||||||
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
@ -153,7 +153,21 @@ func (c *Context) JSON(code int, i interface{}) (err error) {
|
|||||||
return
|
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) {
|
func (c *Context) XML(code int, i interface{}) (err error) {
|
||||||
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
|
@ -11,8 +11,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -94,7 +95,19 @@ func TestContext(t *testing.T) {
|
|||||||
if assert.NoError(t, err) {
|
if assert.NoError(t, err) {
|
||||||
assert.Equal(t, http.StatusOK, rec.Code)
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
assert.Equal(t, ApplicationJSONCharsetUTF8, rec.Header().Get(ContentType))
|
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
|
// XML
|
||||||
|
26
echo.go
26
echo.go
@ -91,18 +91,20 @@ const (
|
|||||||
// Media types
|
// Media types
|
||||||
//-------------
|
//-------------
|
||||||
|
|
||||||
ApplicationJSON = "application/json"
|
ApplicationJSON = "application/json"
|
||||||
ApplicationJSONCharsetUTF8 = ApplicationJSON + "; " + CharsetUTF8
|
ApplicationJSONCharsetUTF8 = ApplicationJSON + "; " + CharsetUTF8
|
||||||
ApplicationXML = "application/xml"
|
ApplicationJavaScript = "application/javascript"
|
||||||
ApplicationXMLCharsetUTF8 = ApplicationXML + "; " + CharsetUTF8
|
ApplicationJavaScriptCharsetUTF8 = ApplicationJavaScript + "; " + CharsetUTF8
|
||||||
ApplicationForm = "application/x-www-form-urlencoded"
|
ApplicationXML = "application/xml"
|
||||||
ApplicationProtobuf = "application/protobuf"
|
ApplicationXMLCharsetUTF8 = ApplicationXML + "; " + CharsetUTF8
|
||||||
ApplicationMsgpack = "application/msgpack"
|
ApplicationForm = "application/x-www-form-urlencoded"
|
||||||
TextHTML = "text/html"
|
ApplicationProtobuf = "application/protobuf"
|
||||||
TextHTMLCharsetUTF8 = TextHTML + "; " + CharsetUTF8
|
ApplicationMsgpack = "application/msgpack"
|
||||||
TextPlain = "text/plain"
|
TextHTML = "text/html"
|
||||||
TextPlainCharsetUTF8 = TextPlain + "; " + CharsetUTF8
|
TextHTMLCharsetUTF8 = TextHTML + "; " + CharsetUTF8
|
||||||
MultipartForm = "multipart/form-data"
|
TextPlain = "text/plain"
|
||||||
|
TextPlainCharsetUTF8 = TextPlain + "; " + CharsetUTF8
|
||||||
|
MultipartForm = "multipart/form-data"
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
// Charset
|
// Charset
|
||||||
|
70
recipes/jsonp/public/index.html
Normal file
70
recipes/jsonp/public/index.html
Normal 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
31
recipes/jsonp/server.go
Normal 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")
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user