JSONP

**JSONP** hay là *JSON với nhãn (padding)* là một dạng bổ sung dựa trên nền định dạng dữ liệu JSON, một *mẫu sử dụng* cho phép trang yêu cầu dữ liệu từ máy chủ trong một tên miền khác. JSONP là một hướng giải quyết cho vấn đề này, hình thành dạng thay thế cho phương thức gần đây nhất có tên là Chia sẻ dữ liệu gốc đan xen (Cross-Origin Resource Sharing).

## Cách hoạt động
Khi trang web có địa chỉ a.com lấy dữ liệu từ một địa chỉ khác là b.com sẽ bị giới hạn gọi là Same origin policy. Theo chính sách này thì các yêu cầu cần phải có cùng một địa chỉ (từ a.com gọi a.com). Để giải quyết vấn đề, giải pháp jsonp được đưa ra với hai bước giải quyết:
* a.com và b.com quy định chung tham số sẽ trả về (ví dụ "callback")trên URL 
* a.com định nghĩa thực hiện (implement) hàm "callback"
* Từ nơi gọi (a.com) dùng javascript yêu cầu (gọi) máy chủ đích (b.com) theo URL quy định ví dụ `http://myserver/getjson?callback=mycallback`
* Máy chủ đích (b.com) xử lý dữ liệu, và thực hiện việc gọi hàm "callback" được truyền theo URL

**Cụ thể mã hoạt động như sau**

* Phía Client (web browser)
Mã nơi gọi yêu cầu (viết với jquery):

```javascript
$.ajax({
  url:"http://myserver/getjson?callback=mycallback", // lưu ý chữ mycallback = hàm phải a.com phải thực hiện,. 
                                                     // ở đây jquery tự động gán vào hàm success,
  data: {"userid": "1234"}, // tùy chọn
  dataType: 'json', 
  success:function(j){
   alert("Success:" +j); // hàm "f"
  },
  error:function(a, b){
   alert("Error");
 }
});
```

* Phía Server

*Lưu ý: Server phải lấy tham số callback gọi từ client*

Mã server trả lời (python)

```python
# 1. lấy tên hàm callback
f = self.request.params.get('callback') # hàm f
# 2. trả lời với dữ liệu json {'a':1}
self.response.out.write(cb+"({a:1})") # tương đương với việc gọi hàm f({a:1})
```


Mã server trả lời (PHP)

```php
// 1. lấy tên hàm callback
$cb = $_GET['callback'] 
# 2. trả lời với dữ liệu json {'a':1}
$array = array('a'=>1);
echo $cb."(".json_encode($array).");"
```


## Nhãn

Trong khi "nhãn" (tiền tố) là đặc trưng cho tên của hàm callback được định nghĩa trong việc thực thi của trình duyệt, nó cũng có thể là một biến gán, một mệnh đề điều kiện, hoặc bất cứ mệnh đề Javascript nào.

Dòng phản hồi tới một yêu cầu JSONP (hay gọi là một phản hồi theo mẫu sử dụng JSONP) không phải là JSON và không phân tích cú pháp như JSON, tải trọng trả về có thể là biểu thức Javascript nào đó và không cần bất cứ dạng JSON nào hết. Tuy nhiên, thông thường nó là đoạn mã Javascript thực hiện gọi hàm trên một vài định JSON. Hay nói cách khác, việc sử dụng một JSONP cung cấp cross-domain truy cập vào một JSON API, bằng cách đóng gói tải trọng JSON trong hàm gọi.

## Vấn đề bảo mật
Các thẻ tag bao gồm trong các máy chủ kết nối cho phép các máy chủ này nhúng bất kỳ nội dung nào vào một website. Nếu máy chủ kết nối có các mối nguy hiểm mà cho phép nhúng mã JavaScript, nguy cơ máy chủ gốc bị tấn công sẽ tăng lên.

Một nỗ lực dùng để định nghĩa một tập giới hạn cho JSON-P  mà các trình duyệt có thể buộc các đoạn kịch bản yêu cầu với dạng MINE đó là "application/json-p". Nếu các phản hồi không phân tích cú pháp như cách các phân tích của JSON-P làm thì trình duyệt sẽ đẩy ra lỗi và bỏ qua toàn bộ dòng nội dung phản hồi.
## Lịch sử
Vào tháng 7 năm 2005,  George Jempty đề nghị một tùy chọn gán biến vào trước JSON.  
Với đề nghị ban đầu cho JSONP, padding là một chức năng gọi lại, xuất hiện đã được thực hiện bởi Bob Ippolito trong tháng 12 năm 2005

## Tham khảo

## Liên kết ngoài
* 
* About JSONP in JavaScript
* jsonp-java wraps any response content into a jsonp callback