javascript - ملفات - مكتبة json




ما هو JSONP؟ (5)

JSONP هو مكان رائع للتخلص من أخطاء البرمجة عبر النطاقات. يمكنك استخدام خدمة JSONP فقط باستخدام JS دون الحاجة إلى تنفيذ وكيل AJAX على جانب الخادم.

يمكنك استخدام خدمة b1t.co لمعرفة كيف يعمل. هذه خدمة JSONP مجانية تسمح لك بتقليل عناوين URL الخاصة بك. هذا هو عنوان URL المستخدم في الخدمة:

http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]

على سبيل المثال ، المكالمة ، http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

سيعود

whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});

وبالتالي عندما يتم تحميل ذلك في js الخاص بك كملف src ، فإنه سيتم تلقائيًا تشغيل أيا كان JavascriptName الذي يجب أن تقوم به كوظيفة رد الاتصال الخاصة بك:

function minifyResultsCallBack(data)
{
    document.getElementById("results").innerHTML = JSON.stringify(data);
}

لإجراء مكالمة JSONP فعليًا ، يمكنك إجراء ذلك عن عدة طرق (بما في ذلك استخدام jQuery) ولكن هنا هو مثال JS خالص:

function minify(urlToMinify)
{
   url = escape(urlToMinify);
   var s = document.createElement('script');
   s.id = 'dynScript';
   s.type='text/javascript';
   s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
   document.getElementsByTagName('head')[0].appendChild(s);
}

مثال خطوة بخطوة وخدمة ويب jsonp لممارسة على متاح في: هذا المنصب

هذا السؤال لديه بالفعل إجابة هنا:

أفهم JSON ، ولكن ليس JSONP. كان مستند ويكيبيديا على JSON (و) أعلى نتيجة بحث لـ JSONP. يقول هذا:

JSONP أو "JSON مع حشوة" هو امتداد JSON حيث يتم تحديد البادئة كوسيطة إدخال للمكالمة نفسها.

هاه؟ اي مكالمه؟ هذا لا يعقلني. JSON هو تنسيق بيانات. لا يوجد مكالمة

نتيجة البحث الثانية هي من شخص اسمه Remy ، الذي يكتب عن JSONP:

JSONP هو إدخال علامة نصي ، ويمرر الاستجابة من الخادم إلى وظيفة محددة للمستخدم.

أستطيع أن أفهم ذلك ، لكنه لا يزال غير منطقي.

إذن ما هو JSONP؟ لماذا تم إنشاؤه (ما المشكلة التي تحلها)؟ ولماذا أستخدمها؟

إضافة : لقد قمت للتو بإنشاء صفحة جديدة لـ JSONP على ويكيبيديا. يحتوي الآن على وصف واضح وشامل لـ JSONP ، استنادًا إلى jvenema .


انها في الواقع ليست معقدة للغاية ...

لنفترض أنك تستخدم النطاق example.com ، وترغب في تقديم طلب إلى المجال example.net. للقيام بذلك ، تحتاج إلى عبور حدود المجال ، لا-لا في معظم التصفح.

العنصر الوحيد الذي يتجاوز هذا القيد هو <script> العلامات. عند استخدام علامة البرنامج النصي ، يتم تجاهل قيود المجال ، ولكن في ظل الظروف العادية ، لا يمكنك فعل أي شيء مع النتائج ، يتم تقييم البرنامج النصي فقط.

أدخل JSONP. عند تقديم طلبك إلى خادم تم تمكين JSONP عليه ، يمكنك تمرير معلمة خاصة تخبر الخادم قليلاً عن صفحتك. وبهذه الطريقة ، يتمكن الخادم من إتمام استجابته بطريقة يمكن لصفحتك التعامل معها.

على سبيل المثال ، لنفترض أن الخادم يتوقع معلمة تسمى "رد الاتصال" لتمكين إمكانات JSONP. ثم سيبدو طلبك:

http://www.example.net/sample.aspx?callback=mycallback

بدون JSONP ، قد يعرض هذا بعض كائنات جافا سكريبت الأساسية ، مثل:

{ foo: 'bar' }

ومع ذلك ، مع JSONP ، عندما يتلقى الخادم معلمة "callback" ، فإنه يختتم النتيجة قليلاً بشكل مختلف ، ويعيد شيئًا كهذا:

mycallback({ foo: 'bar' });

كما ترى ، ستستدعي الآن الطريقة التي حددتها. لذلك ، في صفحتك ، يمكنك تحديد وظيفة رد الاتصال:

mycallback = function(data){
  alert(data.foo);
};

والآن ، عند تحميل النص البرمجي ، سيتم تقييمه وسيتم تنفيذ وظيفتك. Voila ، طلبات عبر النطاقات!

تجدر الإشارة أيضًا إلى المشكلة الرئيسية الوحيدة في JSONP: حيث تفقد قدرًا كبيرًا من التحكم في الطلب. على سبيل المثال ، لا توجد طريقة "لطيفة" للحصول على رموز الفشل المناسبة مرة أخرى. ونتيجة لذلك ، ينتهي الأمر باستخدام أجهزة ضبط الوقت لمراقبة الطلب ، إلخ ، والذي يكون دائمًا مشكوك فيه قليلاً. يمثل اقتراح JSONRequest حلاً رائعًا للسماح JSONRequest عبر النطاقات ، والحفاظ على الأمان ، والسماح بالتحكم المناسب في الطلب.

هذه الأيام (2015) ، CORS هو النهج الموصى به مقابل JSONRequest. لا يزال JSONP مفيدًا لدعم المستعرض الأقدم ، ولكن بالنظر إلى الآثار الأمنية ، ما لم يكن لديك خيار CORS هو الخيار الأفضل.


لأنه يمكنك أن تطلب من الخادم إلحاق بادئة بعنصر JSON الذي تم إرجاعه. على سبيل المثال

function_prefix(json_object);

لكي يتمكن المتصفح من "تضمين" سلسلة JSON كتعبير. تجعل هذه الخدعة من الممكن للملقم أن يقوم "بحقن" شفرة جافا سكريبت مباشرة في مستعرض العميل وهذا مع تجاوز قيود "الأصل نفسه".

بمعنى آخر ، يمكنك تبادل البيانات عبر المجال .

لا يسمح XMLHttpRequest عادةً بتبادل البيانات عبر المجال مباشرة (يحتاج المرء إلى المرور عبر ملقم في نفس المجال) بينما:

<script src="some_other_domain/some_data.js&prefix=function_prefix >` يمكن لأحد الوصول إلى البيانات من نطاق مختلف عن الأصل.

ومن الجدير بالذكر أيضًا: على الرغم من أن الخادم يجب اعتباره "موثوقًا به" قبل محاولة ذلك النوع من "الخدعة" ، يمكن احتواء الآثار الجانبية للتغيير المحتمل في تنسيق الكائن وما إلى ذلك. إذا تم استخدام function_prefix (أي دالة js مناسبة) لتلقي كائن JSON ، فيمكن أن تقوم الوظيفة المذكورة بإجراء عمليات التحقق قبل قبول / معالجة البيانات التي تم إرجاعها.


مثال بسيط لاستخدام JSONP.

client.html

    <html>
    <head>
   </head>
     body>


    <input type="button" id="001" onclick=gO("getCompany") value="Company"  />
    <input type="button" id="002" onclick=gO("getPosition") value="Position"/>
    <h3>
    <div id="101">

    </div>
    </h3>

    <script type="text/javascript">

    var elem=document.getElementById("101");

    function gO(callback){

    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://localhost/test/server.php?callback='+callback;
    elem.appendChild(script);
    elem.removeChild(script);


    }

    function getCompany(data){

    var message="The company you work for is "+data.company +"<img src='"+data.image+"'/   >";
    elem.innerHTML=message;
}

    function getPosition(data){
    var message="The position you are offered is "+data.position;
    elem.innerHTML=message;
    }
    </script>
    </body>
    </html>

server.php

  <?php

    $callback=$_GET["callback"];
    echo $callback;

    if($callback=='getCompany')
    $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})";

    else
    $response="({\"position\":\"Development Intern\"})";
    echo $response;

    ?>    

JSONP هو حقا خدعة بسيطة للتغلب على XMLHttpRequest نهج المجال نفسه. (كما تعلمون ، لا يمكن للمرء إرسال طلب AJAX (XMLHttpRequest) إلى مجال مختلف.)

لذا - بدلاً من استخدام XMLHttpRequest ، يجب علينا استخدام علامات HTML البرمجية ، تلك التي تستخدمها عادةً لتحميل ملفات js ، لكي تحصل js على بيانات من نطاق آخر. يبدو غريب؟

الشيء هو - تبين أنه يمكن استخدام العلامات النصي بطريقة مشابهة ل XMLHttpRequest ! تحقق من هذا:

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data';

سينتهي بك الأمر إلى جزء نصي يبدو كهذا بعد تحميل البيانات:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

ومع ذلك ، هذا غير مريح بعض الشيء ، لأن لدينا لجلب هذه الصفيف من علامة البرنامج النصي . لذا قرر منشئو محتوى JSONP أن هذا سيعمل بشكل أفضل (وهو):

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data?callback=my_callback';

لاحظ وظيفة my_callback هناك؟ لذلك - عندما يتلقى خادم JSONP طلبك ويجد معلمة معاودة الاتصال - بدلاً من عرض مصفوفة js عادي ، سيعود هذا:

my_callback({['some string 1', 'some data', 'whatever data']});

انظر أين يكون الربح: الآن نحصل على رد الاتصال التلقائي (my_callback) الذي سيتم تشغيله بمجرد حصولنا على البيانات.
هذا كل ما يمكن معرفته عن JSONP : إنه عبارة عن علامات رد اتصال ونص.

ملاحظة: هذه أمثلة بسيطة لاستخدام JSONP ، وهذه ليست نصوص جاهزة للإنتاج.

مثال JavaScript أساسي (موجز تويتر بسيط باستخدام JSONP)

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>

مثال jQuery أساسي (موجز تويتر بسيط باستخدام JSONP)

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONP لتقف على JSON مع الحشو . (تقنية تسمى سيئة للغاية لأنها حقا لا علاقة لها بما قد يظن معظم الناس بأنه "الحشو").





terminology