JQuery ছাড়া জাভাস্ক্রিপ্ট থেকে জেএসএনপি অনুরোধ করবেন কীভাবে?


122

আমি জাভাস্ক্রিপ্টে jQuery বা অন্যান্য বাহ্যিক লাইব্রেরি ব্যবহার না করে একটি ক্রস-ডোমেন JSONP অনুরোধ করতে পারি? আমি নিজেই জাভাস্ক্রিপ্ট ব্যবহার করতে চাই এবং তারপরে ডেটা বিশ্লেষণ করে এটিকে একটি বস্তু তৈরি করতে চাই যাতে আমি এটি ব্যবহার করতে পারি। আমার কি কোনও বাহ্যিক গ্রন্থাগার ব্যবহার করতে হবে? যদি না হয় তবে আমি কীভাবে এটি করতে পারি?


উত্তর:


151
function foo(data)
{
    // do stuff with JSON
}

var script = document.createElement('script');
script.src = '//example.com/path/to/jsonp?callback=foo'

document.getElementsByTagName('head')[0].appendChild(script);
// or document.head.appendChild(script) in modern browsers

2
এখানে একটি জেএসবিন রয়েছে যা উইকিপিডিয়া থেকে জেএসএনপি-র সাথে ঝাঁকুনির জন্য ব্যবহার করা যেতে পারে । এটি এই উত্তরে উল্লেখ করা হয়েছিল ।
rkagerer

1
আমি মনে করি এটি প্রতিক্রিয়া হওয়া উচিত যে প্রতিক্রিয়াটি ফর্মের হওয়া উচিত: foo(payload_of_json_data)ধারণাটি হ'ল এটি যখন স্ক্রিপ্ট ট্যাগের মধ্যে লোড হয়ে যায়, এটি ইতিমধ্যে একটি জাভাস্ক্রিপ্ট অবজেক্ট হিসাবে পে-লোড সহ foo ফাংশনটিকে কল করে এবং কোনও পার্সিং প্রয়োজনীয় নয়।
অক্টোপাস

@ উইলমুন আমি জেএসএনপি-র মাধ্যমে এটি করণীয় মনে করি না। এটি প্রাক CORS দিনগুলির একটি হ্যাক। আপনার কীসের জন্য শিরোনাম সেট করতে হবে? সার্ভারকে বিশেষত জেএসএনপি অনুরোধগুলি গ্রহণ করতে হবে তাই এটি বুদ্ধিমানভাবে পরিবেশন করার জন্য সেটআপ করা উচিত।
ম্যাট বল

আপনি ঠিক বলেছেন, আমি কিছু এপিআই ডকুমেন্টেশন ভুলভাবে পড়েছি, জসনপ অ্যাপোলজিগুলি ব্যবহার করার সময় আমি যা চাইছিলাম তা করার জন্য একটি বিশেষ ক্যোয়ারী প্যারামিটার রয়েছে।
মুন

@ উইলমুন কোনও উদ্বেগ নেই। আপনি এটি বাছাই করতে পেরে খুশি!
ম্যাট বল

37

হালকা ওজনের উদাহরণ (অনসেসেস এবং অনটাইমআউট জন্য সমর্থন সহ)। আপনার যদি প্রয়োজন হয় তবে URL এর মধ্যে আপনার কলব্যাক নামটি পাস করতে হবে to

var $jsonp = (function(){
  var that = {};

  that.send = function(src, options) {
    var callback_name = options.callbackName || 'callback',
      on_success = options.onSuccess || function(){},
      on_timeout = options.onTimeout || function(){},
      timeout = options.timeout || 10; // sec

    var timeout_trigger = window.setTimeout(function(){
      window[callback_name] = function(){};
      on_timeout();
    }, timeout * 1000);

    window[callback_name] = function(data){
      window.clearTimeout(timeout_trigger);
      on_success(data);
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = src;

    document.getElementsByTagName('head')[0].appendChild(script);
  }

  return that;
})();

নমুনা ব্যবহার:

$jsonp.send('some_url?callback=handleStuff', {
    callbackName: 'handleStuff',
    onSuccess: function(json){
        console.log('success!', json);
    },
    onTimeout: function(){
        console.log('timeout!');
    },
    timeout: 5
});

গিটহাবে: https://github.com/sobstel/jsonp.js/blob/master/jsonp.js


29

জেএসএনপি কী?

Jsonp এর সাথে মনে রাখা গুরুত্বপূর্ণ বিষয়টি এটি আসলে কোনও প্রোটোকল বা ডেটা টাইপ নয়। ফ্লাইয়ে স্ক্রিপ্ট লোড করা এবং স্ক্রিপ্টটি পৃষ্ঠাতে প্রবর্তন করা হয় এটি প্রক্রিয়াজাত করার একমাত্র উপায়। জেএসএনপি-র স্পিরিটে, এর অর্থ ক্লায়েন্ট অ্যাপ্লিকেশন / স্ক্রিপ্টে সার্ভার থেকে একটি নতুন জাভাস্ক্রিপ্ট অবজেক্ট প্রবর্তন করা।

জেএসএনপি দরকার হয় কখন?

এটি একই পাতায় অসম্পূর্ণভাবে একটি ডোমেনকে অন্যের থেকে ডেটা অ্যাক্সেস / প্রক্রিয়া করার অনুমতি দেওয়ার 1 পদ্ধতি। প্রাথমিকভাবে, এটি সিওআরএস (ক্রস অরিজিন রিসোর্স ভাগ করে নেওয়া) বিধিনিষেধগুলিকে ওভাররাইড করতে ব্যবহৃত হয় যা এক্সএইচআর (এজাক্স) অনুরোধের সাথে সংঘটিত হবে। স্ক্রিপ্ট লোডগুলি CORS বিধিনিষেধের বিষয় নয়।

এটা কিভাবে সম্পন্ন করা হয়

সার্ভার থেকে একটি নতুন জাভাস্ক্রিপ্ট অবজেক্ট উপস্থাপন করা বিভিন্ন উপায়ে প্রয়োগ করা যেতে পারে, তবে সার্ভারের মধ্যে একটি 'কলব্যাক' ফাংশন বাস্তবায়নের জন্য সবচেয়ে সাধারণ অনুশীলন, এতে প্রয়োজনীয় বস্তুটি প্রবেশ করা হয়। কলব্যাক ফাংশন শুধু একটি ফাংশন আপনি ইতিমধ্যে ক্লায়েন্ট যার উপর স্থাপন করেছি স্ক্রিপ্ট আপনি কল সময়ে লোড স্ক্রিপ্ট লোড ডেটা এটি পাস প্রক্রিয়া।

উদাহরণ:

আমার কাছে একটি অ্যাপ্লিকেশন রয়েছে যা কারও বাড়ির সমস্ত আইটেম লগ করে। আমার অ্যাপ্লিকেশনটি সেট আপ হয়েছে এবং আমি এখন মূল শয়নকক্ষের সমস্ত আইটেম পুনরুদ্ধার করতে চাই।

আমার আবেদন চালু আছে app.home.com। আমার যে অ্যাপসটি থেকে ডেটা লোড করা দরকার তা চালু api.home.com

এটির অনুমতি দেওয়ার জন্য সার্ভারটি সুস্পষ্টভাবে সেট আপ না করা না হলে আমি এই ডেটাটি লোড করতে এজ্যাক্স ব্যবহার করতে পারি না, এমনকি পৃথক সাবডোমেনের পৃষ্ঠাগুলিও এক্সএইচআর করস বিধিনিষেধের সাপেক্ষে।

আদর্শভাবে, এক্স-ডোমেন এক্সএইচআর অনুমোদনের জন্য জিনিসগুলি সেট আপ করুন

আদর্শভাবে, যেহেতু এপিআই এবং অ্যাপ্লিকেশন একই ডোমেনে রয়েছে তাই শিরোনামগুলি সেট আপ করতে আমার অ্যাক্সেস থাকতে পারে api.home.com। যদি আমি তা করি তবে আমি Access-Control-Allow-Origin: প্রবেশাধিকার মঞ্জুর করে একটি শিরোনাম আইটেম যুক্ত করতে পারি app.home.com। ধরে Access-Control-Allow-Origin: "http://app.home.com"নিলাম শিরোনামটি নিম্নরূপে সেট আপ করা হয়েছে :, এটি JSONP সেটআপ করার চেয়ে অনেক বেশি সুরক্ষিত। এ কারণে যে app.home.comসবকিছু তা থেকে চায় পেতে পারেন api.home.comছাড়া api.home.comপুরো ইন্টারনেট CORS প্রবেশাধিকার প্রদান।

উপরের এক্সএইচআর সমাধানটি সম্ভব নয়। আমার ক্লায়েন্টের স্ক্রিপ্টে জেএসএনপি সেটআপ করুন: আমি যখন জেএসএনপি কল করি তখন সার্ভার থেকে পুনঃস্থাপন প্রক্রিয়া করার জন্য আমি একটি ফাংশন সেট আপ করি :

function processJSONPResponse(data) {
    var dataFromServer = data;
}

মিনি স্ক্রিপ্টকে এমন কিছু দেখাচ্ছে যাতে ফিরিয়ে আনতে সার্ভারটি সেট আপ করা দরকার "processJSONPResponse('{"room":"main bedroom","items":["bed","chest of drawers"]}');"এটির মতো কোনও কিছু //api.home.com?getdata=room&room=main_bedroomবলা হয়ে থাকলে এটি এমন স্ট্রিং ফেরত দেওয়ার জন্য নকশাকৃত হতে পারে ।

তারপরে ক্লায়েন্ট যেমন একটি স্ক্রিপ্ট ট্যাগ সেট আপ করে:

var script = document.createElement('script');
script.src = '//api.home.com?getdata=room&room=main_bedroom';

document.querySelector('head').appendChild(script);

এটি স্ক্রিপ্টটি লোড করে এবং তত্ক্ষণাত window.processJSONPResponse()সার্ভারের দ্বারা লিখিত / প্রতিধ্বনি / মুদ্রিত হিসাবে কল করে। ফাংশনটির প্যারামিটার হিসাবে পাস করা ডেটা এখন dataFromServerস্থানীয় ভেরিয়েবলে সঞ্চিত এবং আপনি যা প্রয়োজন তা এটি করতে পারেন।

পরিষ্কার কর

ক্লায়েন্টের একবার ডেটা, অর্থাৎ ie স্ক্রিপ্টটি ডিওমে যুক্ত হওয়ার সাথে সাথেই স্ক্রিপ্টের উপাদানটি ডিওএম থেকে সরানো যেতে পারে:

script.parentNode.removeChild(script);

2
অনেক ধন্যবাদ, এটি আমার প্রকল্পে আমাকে খুব সাহায্য করেছে। একটি ছোটখাটো সমস্যা: আমি পেয়েছি SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data। : তথ্য একক উদ্ধৃতি যোগ করার পর, সবকিছু ঠিক আছে, তাই কাজ"processJSONPResponse('{"room":"main bedroom","items":["bed","chest of drawers"]}');"
হেইন ভ্যান ডাইকি

17

আমার বোধগম্যতা হল আপনি আসলে JSONP, sooo এর সাথে স্ক্রিপ্ট ট্যাগ ব্যবহার করেন ...

প্রথম পদক্ষেপটি আপনার ফাংশন তৈরি করা যা JSON পরিচালনা করবে:

function hooray(json) {
    // dealin wit teh jsonz
}

নিশ্চিত করুন যে এই কার্যটি বিশ্বব্যাপী অ্যাক্সেসযোগ্য।

এর পরে, ডিওমে একটি স্ক্রিপ্ট উপাদান যুক্ত করুন:

var script = document.createElement('script');
script.src = 'http://domain.com/?function=hooray';
document.body.appendChild(script);

স্ক্রিপ্টটি API সরবরাহকারী যে জাভাস্ক্রিপ্টটি লোড করবে এবং এটি সম্পাদন করবে।


2
ধন্যবাদ সবাইকে. কিছু ডেটার সন্ধানে ইন্টারনেটে এটির শুটিং পেয়েছে এবং তারপরে আমি এটি দিয়ে কিছু করি। আমি প্রতিক্রিয়ার ডেটাগুলিতে eval () ব্যবহার করেছি যা আমাকে অবজেক্টটি মোকাবেলায় সহায়তা করেছিল - অ্যারে এটি (আমি মনে করি)। {এটি আমার সীমাবদ্ধ শক্তিশক্তির সাথে বিশ্লেষণকারী এক ভাল্লুক ছিল তবে অবশেষে আমি এটি থেকে মূল্য টানতে পেরেছি} ফ্যান্টাস্টিক।
ডেভ

@Dave @Matt হয়তো আমি নই jsonp উপর ঝাপসা, কিন্তু আপনি প্রয়োজন করা উচিত নয় evalবা parseকিছু বা। আপনার জাভাস্ক্রিপ্ট পাওয়া উচিত যা ব্রাউজারটি ঠিক চালিয়ে দিতে পারে, তাই না?
sdleihssirhc

আমার খারাপ, বিভ্রান্তির জন্য দুঃখিত। অ্যারের থেকে জিনিসটি (মান? সম্পত্তি?) পাওয়ার চেষ্টা করছিল আমার মাথা স্পিন করে তুলছে (নীড়, কলব্যাক, অ্যারে, উপাদান, স্ট্রিং, মান, কোঁকড়ানো বন্ধনী, বন্ধনী ...)। আমি আমার eval এর ব্যবহার সরিয়ে দিয়েছি এবং এখনও আমি (সারণি (উপাদান? উপাদান?) অ্যারে থেকে সম্পত্তি (মান?) পেয়েছি।
ডেভ

10

নীচের মতো আমি jsonp ব্যবহার করার উপায়:

function jsonp(uri) {
    return new Promise(function(resolve, reject) {
        var id = '_' + Math.round(10000 * Math.random());
        var callbackName = 'jsonp_callback_' + id;
        window[callbackName] = function(data) {
            delete window[callbackName];
            var ele = document.getElementById(id);
            ele.parentNode.removeChild(ele);
            resolve(data);
        }

        var src = uri + '&callback=' + callbackName;
        var script = document.createElement('script');
        script.src = src;
        script.id = id;
        script.addEventListener('error', reject);
        (document.getElementsByTagName('head')[0] || document.body || document.documentElement).appendChild(script)
    });
}

তারপরে 'jsonp' পদ্ধতিটি ব্যবহার করুন:

jsonp('http://xxx/cors').then(function(data){
    console.log(data);
});

রেফারেন্স:

জাভাস্ক্রিপ্ট এক্সএমএলএইচটিপি জেএসএনপি ব্যবহার করে অনুসন্ধান করুন

http://www.w3ctech.com/topic/721 (প্রতিশ্রুতি ব্যবহারের উপায় সম্পর্কে কথা বলুন)


1
অ্যাসাইনমেন্টগুলি স্ক্রিপ্ট করুন rc src = src; যুক্ত করুন ';' সমস্ত অ্যাসাইনমেন্টের শেষে
chdev77

6

এটি করার জন্য আমার একটি খাঁটি জাভাস্ক্রিপ্ট লাইব্রেরি আছে https://github.com/robertodecurnex/J50Npi/blob/master/J50Npi.js

এটি একবার দেখুন এবং কোডটি ব্যবহার করতে বা বোঝার জন্য আপনার কোনও সহায়তা প্রয়োজন কিনা তা আমাকে জানান।

বিটিডব্লিউ, আপনার এখানে ব্যবহারের সহজ উদাহরণ রয়েছে: http://robertodecurnex.github.com/J50Npi/


6
আপনার সমাধানটি আমার ব্যবহারের ক্ষেত্রে কিছুটা সহজ ছিল, তাই আমি একাধিক অনুরোধ সমর্থন যোগ করেছি gist.github.com/1431613
চাদ সায়রা

5
/**
 * Loads data asynchronously via JSONP.
 */
const load = (() => {
  let index = 0;
  const timeout = 5000;

  return url => new Promise((resolve, reject) => {
    const callback = '__callback' + index++;
    const timeoutID = window.setTimeout(() => {
      reject(new Error('Request timeout.'));
    }, timeout);

    window[callback] = response => {
      window.clearTimeout(timeoutID);
      resolve(response.data);
    };

    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = url + (url.indexOf('?') === -1 ? '?' : '&') + 'callback=' + callback;
    document.getElementsByTagName('head')[0].appendChild(script);
  });
})();

ব্যবহারের নমুনা:

const data = await load('http://api.github.com/orgs/kriasoft');

1
window[callback] = nullফাংশনটি আবর্জনা সংগ্রহ করার অনুমতি দিতে ভুলবেন না ।
সুকিমা

3

এটিকে পরিচালনা করার জন্য আমি একটি লাইব্রেরি লিখেছি, যতটা সম্ভব সম্ভব। এটি বাহ্যিক করার দরকার নেই, এটি কেবল একটি ফাংশন। অন্য কয়েকটি বিকল্পের বিপরীতে, এই স্ক্রিপ্টটি নিজের পরে পরিষ্কার হয়ে যায়, এবং রানটাইমে আরও অনুরোধ করার জন্য সাধারণীকরণ করা হয়।

https://github.com/Fresheyeball/micro-jsonp

function jsonp(url, key, callback) {

    var appendParam = function(url, key, param){
            return url
                + (url.indexOf("?") > 0 ? "&" : "?")
                + key + "=" + param;
        },

        createScript = function(url, callback){
            var doc = document,
                head = doc.head,
                script = doc.createElement("script");

            script
            .setAttribute("src", url);

            head
            .appendChild(script);

            callback(function(){
                setTimeout(function(){
                    head
                    .removeChild(script);
                }, 0);
            });
        },

        q =
            "q" + Math.round(Math.random() * Date.now());

    createScript(
        appendParam(url, key, q), function(remove){
            window[q] =
                function(json){
                    window[q] = undefined;
                    remove();
                    callback(json);
                };
        });
}

2

JQuery ছাড়াই কল JavaScriptকরার জন্য দয়া করে নীচের উদাহরণটি সন্ধান করুন JSONP:

এছাড়াও, আপনি GitHubরেফারেন্সের জন্য আমার সংগ্রহস্থলটি উল্লেখ করতে পারেন ।

https://github.com/shedagemayur/JavaScriptCode/tree/master/jsonp

window.onload = function(){
    var callbackMethod = 'callback_' + new Date().getTime();

    var script = document.createElement('script');
    script.src = 'https://jsonplaceholder.typicode.com/users/1?callback='+callbackMethod;

    document.body.appendChild(script);

    window[callbackMethod] = function(data){
        delete window[callbackMethod];
        document.body.removeChild(script);
        console.log(data);
    }
}


0
/**
 * Get JSONP data for cross-domain AJAX requests
 * @private
 * @link http://cameronspear.com/blog/exactly-what-is-jsonp/
 * @param  {String} url      The URL of the JSON request
 * @param  {String} callback The name of the callback to run on load
 */
var loadJSONP = function ( url, callback ) {

    // Create script with url and callback (if specified)
    var ref = window.document.getElementsByTagName( 'script' )[ 0 ];
    var script = window.document.createElement( 'script' );
    script.src = url + (url.indexOf( '?' ) + 1 ? '&' : '?') + 'callback=' + callback;

    // Insert script tag into the DOM (append to <head>)
    ref.parentNode.insertBefore( script, ref );

    // After the script is loaded (and executed), remove it
    script.onload = function () {
        this.remove();
    };

};

/** 
 * Example
 */

// Function to run on success
var logAPI = function ( data ) {
    console.log( data );
}

// Run request
loadJSONP( 'http://api.petfinder.com/shelter.getPets?format=json&key=12345&shelter=AA11', 'logAPI' );

কেন window.document.getElementsByTagName('script')[0];এবং না document.body.appendChild(…)?
সুকিমা

আবর্জনা সংগ্রহের কাজটি logAPIকরা nullগেলে এটি সেট করা উচিত নয় ?
সুকিমা

0

আপনি যদি এনপিএম সহ ES6 ব্যবহার করে থাকেন তবে নোড মডিউল "ফেচ-জসনপ" ব্যবহার করতে পারেন। ফেচ এপিআই একটি নিয়মিত এক্সএইচআর কল হিসাবে জসনপি কল করার জন্য সহায়তা সরবরাহ করে।

পূর্বশর্ত: isomorphic-fetchআপনার স্ট্যাকের নোড মডিউলটি ব্যবহার করা উচিত ।


0

কেবল সাবস্টেলের চমৎকার উত্তরের একটি ES6 সংস্করণ আটকানো:

send(someUrl + 'error?d=' + encodeURI(JSON.stringify(json)) + '&callback=c', 'c', 5)
    .then((json) => console.log(json))
    .catch((err) => console.log(err))

function send(url, callback, timeout) {
    return new Promise((resolve, reject) => {
        let script = document.createElement('script')
        let timeout_trigger = window.setTimeout(() => {
            window[callback] = () => {}
            script.parentNode.removeChild(script)
            reject('No response')
        }, timeout * 1000)

        window[callback] = (data) => {
            window.clearTimeout(timeout_trigger)
            script.parentNode.removeChild(script)
            resolve(data)
        }

        script.type = 'text/javascript'
        script.async = true
        script.src = url

        document.getElementsByTagName('head')[0].appendChild(script)
    })
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.