JavaScript: How do I create JSONP?

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

I have a two domains, example1.com and example2.com

From example1.com, I would like call a JSON API I have on example2.com. Knowing that this is not allowed, it occurred to me - this is exactly why JSONP was created.

Question is, how do I modify my JSON API to make it JSONP capable?

Basically, how do I create the callback api?

UPDATE

My server side language is PHP

回答1:

It is simple. Simply accept a parameter called callback in the GET.

Then wrap the callback JavaScript function around your data.

Example in 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; } 

It's idea is to simply return a JavaScript file which calls the callback function with the JSON object as the first parameter of the JavaScript callback function.

You can use the built-in json_encode() function to create JSON strings (which $data in our example above contains) from arrays and objects in PHP.

To use the JSONP service, you can use the <script> tag:

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


回答2:

You need a server-side language, the callback parameter is simply a GET parameter, you read the param, and you wrap the JSON response into a function call and you print it like this callback(jsonResponse);.

I leave you a really minimalist example using Python since you don't mention any server-side language:

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 

That is the code of a small JSONP service used to retrieve the client IP address made by Zach and it is hosted on the Google App Engine.



回答3:

Mauris already gave you a working example. I would only add that you should check if a callback param is present and non-empty, and if not, return the json data as is without the parentheses. So basically your api will be JSON with provision of being JSON-P when callback is given.

To consume the JSON-P webservice, unless you use a framework like YUI or jQuery, you can simply create a script node dynamically and set its src attribute to point to the webservice. Remember to remove the node from the dom before repeating it again, since this dynamic script node is single use only.



回答4:

I know I'm late to the party, and there was a comment about security of the code in one of the answers. Here is a good article about this:

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

And here is the code that you should be running:

<?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); 


回答5:

// Adds script tag to head of the page function addScriptToHead(source, code, type) {     var script = document.createElement('script');     if (type === 'js') {         script.setAttribute('type', 'text/javascript');     }     if (source !== '') {         script.setAttribute('src', source);     }     if (code !== '') {         if (document.all && !window.opera)  {             script.text = code;         } else {             script.innerHTML = code;         }     }     document.getElementsByTagName('head')[0].appendChild(script); }   // Callback function function addScriptToHead(any_param) {  // do whatever needs to be done  }  //call example  addScriptToHead('http://url_to_receiver_script/index.php&param=anything', '', 'js'); 

/// the callback script should return name of the Callback function, i.e. if you type in browser

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

it should return just a text (name of existing processing function): addScriptToHead(any_param)

works like a clock in any browser.



回答6:

Easy with jQuery, that is the client side:

  $.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]);   } } } 

And be sure that you get proper json from the server side;
and don't forget to return the jsonp_callback param, otherwise it won't work!!!!!
and that's it really.



回答7:

example here http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html basically

<script src=".../example2...?output=json;callback=loadit"></script> <script> alert( "I got this from example2 " + loadit); </script> 


回答8:

You can use the Simple JSON for PHP to forge it! It simplify everything!

<?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(); ?> 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!