2009-11-05 34 views
39

मैं एक दो डोमेन, example1.com और example2.comजावास्क्रिप्ट: मैं JSONP कैसे बना सकता हूं?

example1.com से है, मैं मैं example2.com पर एक JSON एपीआई फोन चाहते हैं। यह जानकर कि इसकी अनुमति नहीं है, यह मेरे लिए हुआ - यही कारण है कि JSON पी बनाया गया था।

प्रश्न यह है कि, मैं JSONP को सक्षम करने के लिए अपने JSON API को कैसे संशोधित करूं?

असल में, मैं कॉलबैक एपीआई कैसे बना सकता हूं?

अद्यतन

मेरे सर्वर साइड भाषा पीएचपी

है

उत्तर

26

आप एक सर्वर साइड भाषा की जरूरत है, कॉलबैक पैरामीटर बस एक प्राप्त पैरामीटर है , आप परम पढ़ते हैं, और आप JSON प्रतिक्रिया को फ़ंक्शन कॉल में लपेटते हैं और आप इसे callback(jsonResponse); जैसे प्रिंट करते हैं।

import os 
import cgi 

form = cgi.FieldStorage() 
callback = form.getvalue('callback','') 

address = cgi.escape(os.environ["REMOTE_ADDR"]) 

json = '{"ip": "'+address+'", "address":"'+address+'"}' 

#Allow cross domain XHR 
print 'Access-Control-Allow-Origin: *' 
print 'Access-Control-Allow-Methods: GET' 

if callback != '': 
    print 'Content-Type: application/javascript' 
    result = callback+'('+json+');' 
else: 
    print 'Content-Type: application/json' 
    result = json 

print '' 
print result 

एक छोटे से JSONP service ग्राहक आईपी पते को पुनः प्राप्त करने के लिए इस्तेमाल की कोड Zach द्वारा बनाई गई है कि:

मैं तुम्हें एक बहुत सरल उदाहरण अजगर का उपयोग कर के बाद से आप किसी भी सर्वर साइड भाषा का उल्लेख नहीं है छोड़ और यह Google App Engine पर होस्ट किया गया है।

+0

आपका कोड खूबसूरती से काम करता है और बहुत ही सुरुचिपूर्ण है! – TruMan1

+0

यह उत्तर –

73

यह आसान है। बस GET में callback नामक पैरामीटर को स्वीकार करें।

फिर अपने डेटा के चारों ओर कॉलबैक जावास्क्रिप्ट फ़ंक्शन को लपेटें। PHP में

उदाहरण:

<?php 

$data = '{}'; // json string 

if(array_key_exists('callback', $_GET)){ 

    header('Content-Type: text/javascript; charset=utf8'); 
    header('Access-Control-Allow-Origin: http://www.example.com/'); 
    header('Access-Control-Max-Age: 3628800'); 
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); 

    $callback = $_GET['callback']; 
    echo $callback.'('.$data.');'; 

}else{ 
    // normal JSON string 
    header('Content-Type: application/json; charset=utf8'); 

    echo $data; 
} 

यह विचार है बस किसी JavaScript फ़ाइल जो जावास्क्रिप्ट कॉलबैक फ़ंक्शन के पहले पैरामीटर के रूप में JSON ऑब्जेक्ट के साथ कॉलबैक फ़ंक्शन को कॉल वापस जाने के लिए है।

आप उपयोग कर सकते हैं में निर्मित json_encode() समारोह JSON तार (हमारे उदाहरण में $data ऊपर होता है जो) सरणियों और PHP में वस्तुओं से बनाने के लिए।

JSONP सेवा का उपयोग करने के लिए आपको <script> टैग का उपयोग कर सकते हैं:

<script> 
    function receiver(data){ 
     console.log(data); 
    } 
</script> 
<script src="data-service.php?callback=receiver"></script> 
+4

वाह स्वीकार किया जाना चाहिए, क्या यह वास्तव में बस इतना है? – Teddi

+0

क्या मुझे जोड़ने की ज़रूरत है: echo 'एक्सेस-कंट्रोल-अनुमति-उत्पत्ति: *' गूंज 'एक्सेस-कंट्रोल-अनुमति-तरीके: प्राप्त करें' ??? – Teddi

+0

@ टेडी: उन शीर्षकों को आगामी XMLHttpRequest 2 विनिर्देश (http://www.w3.org/TR/access-control/) और बीटीडब्लू का समर्थन करना है, वे पहले ही फ़ायरफ़ॉक्स 3.5 (https://developer.mozilla.org पर काम करते हैं)/en/HTTP_access_control) – CMS

6

Mauris पहले से ही आप एक काम उदाहरण दिया। मैं केवल यह जोड़ूंगा कि आपको यह जांचना चाहिए कि callback परम मौजूद है और खाली नहीं है, और यदि नहीं, तो जेएसन डेटा को कोष्ठक के बिना वापस लौटाएं। इसलिए मूल रूप से आपका एपीआई JSON-P होने के प्रावधान के साथ JSON होगा जब callback दिया गया है।

JSON-P webservice का उपभोग करने के लिए, जब तक आप YUI या jQuery जैसे ढांचे का उपयोग नहीं करते हैं, तो आप बस स्क्रिप्ट नोड गतिशील रूप से बना सकते हैं और webservice को इंगित करने के लिए src विशेषता सेट कर सकते हैं। इसे फिर से दोहराने से पहले डोम से नोड को निकालना याद रखें, क्योंकि यह गतिशील स्क्रिप्ट नोड केवल एकल उपयोग है।

2

jQuery के साथ आसान, क्लाइंट पक्ष यह है कि:

$.ajax({ 
     dataType: 'jsonp', 
     data: "somedata="+somevalue, 
     //this is very important since it's the callback we will and that allow cross domain 
     jsonp: 'jsonp_callback', 
     url: 'http://example2.com', 
     //function we trigger on success 
     success: ParseJson 
     //error handling not working with jsonP 
     //error: handleError 
     }); 

function ParseJson(data) 
{ 
for (var key in data) { 
    if (data.hasOwnProperty(key)) { 
    alert(key + " -> " + data[key]); 
    } 
} 
} 

और सुनिश्चित करें कि आप सर्वर साइड से उचित json प्राप्त हो सकता है;
और jsonp_callback param वापस करने के लिए मत भूलना, अन्यथा यह काम नहीं करेगा !!!!!
और यह वास्तव में है।

3

/// कॉलबैक स्क्रिप्ट, कॉलबैक समारोह के नाम पर लौटना चाहिए यानी अगर आप ब्राउज़र में लिखे गए

http://url_to_receiver_script/index.php&param=anything

यह सिर्फ एक पाठ (मौजूदा प्रसंस्करण समारोह का नाम) वापसी करना चाहिए: addScriptToHead (any_param)

किसी भी ब्राउज़र में घड़ी की तरह काम करता है।

4

मुझे पता है कि मैं पार्टी के लिए देर हो चुकी हूं, और उत्तर में से किसी एक में कोड की सुरक्षा के बारे में एक टिप्पणी थी।

http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/

यहाँ और कोड द्वारा चलाए किया जाना चाहिए:: यहाँ इस बारे में एक अच्छा लेख है

<?php header('content-type: application/json; charset=utf-8'); 

function is_valid_callback($subject) 
{ 
    $identifier_syntax 
     = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u'; 

    $reserved_words = array('break', 'do', 'instanceof', 'typeof', 'case', 
     'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 
     'for', 'switch', 'while', 'debugger', 'function', 'this', 'with', 
     'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 
     'extends', 'super', 'const', 'export', 'import', 'implements', 'let', 
     'private', 'public', 'yield', 'interface', 'package', 'protected', 
     'static', 'null', 'true', 'false'); 

    return preg_match($identifier_syntax, $subject) 
     && ! in_array(mb_strtolower($subject, 'UTF-8'), $reserved_words); 
} 

$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9); 
$json = json_encode($data); 

# JSON if no callback 
if(! isset($_GET['callback'])) 
    exit($json); 

# JSONP if valid callback 
if(is_valid_callback($_GET['callback'])) 
    exit("{$_GET['callback']}($json)"); 

# Otherwise, bad request 
header('status: 400 Bad Request', true, 400); 
+0

यदि किसी को भी कोणीय का उपयोग कर रहा है, तो यह काम नहीं करेगा। कोणीय jsonp का समर्थन करता है, लेकिन कॉलबैक को 'angular.callback._0' जैसे कुछ के साथ बदल देता है। इस तरह की कॉलबैक की अनुमति असुरक्षित होगी? –

+0

@BobVork मुझे विश्वास नहीं है, आप अवधि भी शामिल करने के लिए '$ identifier_syntax' को बदल सकते हैं। असल में, मेरा मानना ​​है कि मैंने उस कारण के लिए अपने कार्यान्वयन में ऐसा करना समाप्त कर दिया (लेकिन मैंने अपना कार्यान्वयन पूरा करने से पहले इसे पोस्ट किया)। – jkinz

0

आप Simple JSON for PHP उपयोग कर सकते हैं यह बनाने के लिए! यह सब कुछ सरल बनाता है!

<?php 

    include('../includes/json.php'); 

    $json = new json('callback', 'myCallback'); 

    $object = new stdClass(); 
    $object->FirstName = 'John'; 
    $object->LastName = 'Doe'; 
    $array = array(1,'2', 'Pieter', true); 
    $jsonOnly = '{"Hello" : "darling"}'; 
    // Add objects to send 
    $json->add('status', '200'); 
    $json->add("worked"); 
    $json->add("things", false); 
    $json->add('friend', $object); 
    $json->add("arrays", $array); 
    $json->add("json", $jsonOnly, false); 

    /* 
    Expected result : 
    myCallback({ 
    "status": "200", 
    "worked": true, 
    "things": false, 
    "friend": { 
     "FirstName": "John", 
     "LastName": "Doe" 
    }, 
    "arrays": [ 
     1, 
     "2", 
     "Pieter", 
     true 
    ], 
    "json": { 
     "Hello": "darling" 
    } 
    }); 

    */ 
    $json->send(); 
?> 
संबंधित मुद्दे