JsonP के लिए डेटा पोस्ट करें


102

क्या JsonP पर डेटा पोस्ट करना संभव है? या क्या जीईटी अनुरोध के रूप में सभी डेटा को क्वेरिस्ट्रिंग में पारित करना होगा?

मेरे पास डेटा का एक बहुत है जिसे मुझे सेवा, क्रॉस डोमेन पर भेजने की आवश्यकता है, और यह बहुत बड़ा है जिसे क्वेरिस्ट्रिंग के माध्यम से भेजना है

इसके आस-पास होने के लिए क्या विकल्प हैं?

जवाबों:


83

एक ही मूल नीतिPOST की (काफी समझदार) सीमा के कारण किसी अन्य डोमेन पर एक सेवा के लिए एक अतुल्यकालिक करना संभव नहीं है । JSON-P केवल इसलिए काम करता है क्योंकि आपको DOM में टैग डालने की अनुमति है , और वे कहीं भी इंगित कर सकते हैं।<script>

आप निश्चित रूप से किसी अन्य डोमेन पर एक पेज बना सकते हैं, जो एक नियमित फॉर्म POST की क्रिया है।

संपादित करें : वहाँ कुछ दिलचस्प हैक कर रहे हैं यदि आप बहुत सारे प्रयास करने के लिए तैयार हैं, जिसमें छिपे हुए <iframe>एस और उनके गुणों के बारे में मैकिंग सम्मिलित करने के लिए तैयार हैं।


आपने उल्लेख किया है कि "एसिंक्रोनस POST" संभव नहीं है .... तो क्या मैं एक तुल्यकालिक POST कर सकता हूं?
मार्क

4
@मार्क "सिंक्रोनस POST" का अर्थ है एक ऐसा फॉर्म सबमिट करना जो <फॉर्म मेथड = "पोस्ट" एक्शन = "http: // ... / ..."> का उपयोग करता है
स्टीवन क्रिस्कल्ला

8
यह बिल्कुल सच नहीं है। आप निश्चित रूप POSTसे अन्य डोमेन के लिए अनुरोध कर सकते हैं जब तक कि डोमेन और आपका ब्राउज़र समर्थन दोनों CORS। लेकिन यह पूरी तरह से सच है POSTऔर JSONPसंगत नहीं है।
हिप्पिट्रैएल

2
JSONP उन <script>टैगों को सम्मिलित करके कार्यान्वित किया जाता है जो किसी अन्य डोमेन को इंगित करते हैं। ब्राउज़र में POST अनुरोधों को निष्पादित करने का एकमात्र तरीका HTML रूपों या XMLHttpRequest के माध्यम से है।
फ्राइडो

1
(सामान्य रूप से -) यह एक अन्य डोमेन पर एक सेवा के लिए एक अतुल्यकालिक पोस्ट करने के लिए (!) संभव है। प्रतिक्रिया पर सीमा है। सीमा JSONP अनुरोध पर भी है।
रॉय नमिर

20

यदि आपको बहुत सारा डेटा क्रॉस-डोमेन भेजने की आवश्यकता है। मैं आमतौर पर एक सेवा बनाता हूं जिसे आप दो चरणों में कॉल कर सकते हैं:

  1. पहले ग्राहक एक FORM सबमिट करते हैं (पोस्ट अनुमति क्रॉस डोमेन)। सेवा सर्वर पर सत्र में इनपुट संग्रहीत करती है (कुंजी के रूप में GUID का उपयोग करके)। (ग्राहक एक GUID बनाता है और इसे इनपुट के एक भाग के रूप में भेजता है)

  2. फिर क्लाइंट एक सामान्य स्क्रिप्ट-इंजेक्शन (JSONP) करता है, एक पैरामीटर के रूप में आप उसी GUID का उपयोग करते हैं जैसा आपने FORM पोस्ट में उपयोग किया था। सेवा सत्र से इनपुट को संसाधित करती है और डेटा को सामान्य JSONP-फ़ैशन में वापस करती है। इसके बाद सत्र नष्ट हो जाता है।

यह निश्चित रूप से इस पर निर्भर करता है कि आप सर्वर-बैकेंड लिखते हैं।


1
अपने aproach की कोशिश की। FF14 और Chrome20 के लिए काम किया। ओपेरा 11 और IE9 ने केवल पोस्ट को स्थानांतरित नहीं किया। (यह उनके डिबग टूल के साथ जांचा गया और दूसरे छोर पर सर्वर पर सुना गया) हो सकता है कि IE की विकलांगता से संबंधित है यह सवाल: stackoverflow.com/questions/10395803/… कंसोल में क्रोम शिकायत, लेकिन फिर भी पोस्ट नहीं किया: XMLHttpRequest नहीं कर सकता लोड लोकलहोस्ट: 8080 / xxx ओरिजिनल नल एक्सेस-कंट्रोल-अलाउंस-ओरिजिन द्वारा अनुमति नहीं है।
वनवर्ल्ड जूल

@OneWorld - आपने वह नहीं किया जो उत्तर ने कहा था। XMLHttpRequestबिल्कुल शामिल नहीं होना चाहिए। प्रति उत्तर POST अनुरोध करने के लिए एक नियमित रूप से प्रस्तुत करने का उपयोग करता है, फिर GET अनुरोध करने के लिए एक स्क्रिप्ट तत्व इंजेक्शन।
क्वेंटिन

7

मुझे पता है कि यह गंभीर नेक्रोमेंसी है, लेकिन मुझे लगा कि मैं JSONP POST के कार्यान्वयन को jQuery का उपयोग करके पोस्ट करूंगा, जिसे मैं अपने JS विजेट के लिए सफलतापूर्वक उपयोग कर रहा हूं (यह ग्राहक पंजीकरण और लॉगिन के लिए उपयोग किया जाता है):

मूल रूप से, मैं एक IFrame दृष्टिकोण का उपयोग कर रहा हूं, जैसा कि स्वीकृत उत्तर में सुझाया गया है। अनुरोध भेजने के बाद मैं जो कुछ अलग कर रहा हूं, मैं वॉचिन हूं, अगर टाइमर का उपयोग करके फॉर्म को आइफ्रेम में पहुंचा जा सकता है। जब फॉर्म तक नहीं पहुंचा जा सकता है, तो इसका मतलब है कि अनुरोध वापस आ गया है। फिर, मैं ऑपरेशन की स्थिति के लिए क्वेरी करने के लिए एक सामान्य JSONP अनुरोध का उपयोग कर रहा हूं।

मुझे आशा है कि किसी को यह उपयोगी लगता है। > = IE8, क्रोम, फायरफॉक्स और सफारी में परीक्षण किया गया।

function JSONPPostForm(form, postUrl, queryStatusUrl, queryStatusSuccessFunc, queryStatusData)
{
    var tmpDiv = $('<div style="display: none;"></div>');
    form.parent().append(tmpDiv);
    var clonedForm = cloneForm(form);
    var iframe = createIFrameWithContent(tmpDiv, clonedForm);

    if (postUrl)
        clonedForm.attr('action', postUrl);

    var postToken = 'JSONPPOST_' + (new Date).getTime();
    clonedForm.attr('id', postToken);
    clonedForm.append('<input name="JSONPPOSTToken" value="'+postToken+'">');
    clonedForm.attr('id', postToken );
    clonedForm.submit();

    var timerId;
    var watchIFrameRedirectHelper = function()
    {
        if (watchIFrameRedirect(iframe, postToken ))
        {
            clearInterval(timerId);
            tmpDiv.remove();
            $.ajax({
                url:  queryStatusUrl,
                data: queryStatusData,
                dataType: "jsonp",
                type: "GET",
                success: queryStatusSuccessFunc
            });
        }
    }

    if (queryStatusUrl && queryStatusSuccessFunc)
        timerId = setInterval(watchIFrameRedirectHelper, 200);
}

function createIFrameWithContent(parent, content)
{
    var iframe = $('<iframe></iframe>');
    parent.append(iframe);

    if (!iframe.contents().find('body').length)
    {
        //For certain IE versions that do not create document content...
        var doc = iframe.contents().get()[0];
        doc.open();
        doc.close();
    }

    iframe.contents().find('body').append(content);
    return iframe;
}

function watchIFrameRedirect(iframe, formId)
{
    try
    {
        if (iframe.contents().find('form[id="' + formId + '"]').length)
            return false;
        else
            return true;
    }
    catch (err)
    {
        return true;
    }
    return false;
}

//This one clones only form, without other HTML markup
function cloneForm(form)
{
    var clonedForm = $('<form></form>');
    //Copy form attributes
    $.each(form.get()[0].attributes, function(i, attr)
    {
        clonedForm.attr(attr.name, attr.value);
    });
    form.find('input, select, textarea').each(function()
    {
        clonedForm.append($(this).clone());
    });

    return clonedForm;
}

4

आम तौर पर JSONP को <script>कॉलिंग दस्तावेज़ में एक टैग जोड़कर लागू किया जाता है , जैसे कि JSONP सेवा का URL "src" है। ब्राउज़र एक HTTP GET लेनदेन के साथ स्क्रिप्ट स्रोत प्राप्त करता है।

अब, यदि आपकी JSONP सेवा आपके कॉलिंग पेज के समान डोमेन में है, तो आप संभवतः एक साधारण $.ajax()कॉल के साथ कुछ और कर सकते हैं। यदि यह एक ही डोमेन में नहीं है, तो मुझे यकीन नहीं है कि यह कैसे संभव होगा।


यह इस मामले में एक ही डोमेन में नहीं है। और मैं यह मान रहा हूँ कि केवल GET संभव है, लेकिन मैं केवल JsonP के बारे में पढ़ना शुरू कर चुका हूँ, और इस पर कुछ निर्णय लेने की आवश्यकता है कि क्या मुझे इसकी आवश्यकता है
क्रिसका

2
यदि यह एक ही डोमेन में नहीं है, लेकिन यह समर्थन करता है CORSतो यह तब तक संभव होगा जब तक ब्राउज़र भी इसका समर्थन करता है। इन मामलों में आप सादे के JSONबजाय का उपयोग करेंगे JSONP
हिप्पिट्रैएल

हां, @hippietrail 2 साल एक बड़ा अंतर बनाता है :-) CORS यह निश्चित रूप से संभव बनाता है, लेकिन निश्चित रूप से यह आवश्यक है कि डेटा स्रोत को उचित रूप से सेट किया जाए।
नुकीले

0

आप इस परियोजना का उपयोग कर एक कोर प्रॉक्सी का उपयोग कर सकते हैं । यह आपके डोमेन पर एक समापन बिंदु के लिए सभी ट्रैफ़िक को निर्देशित करेगा और उस जानकारी को किसी बाहरी डोमेन पर रिले करेगा। चूंकि ब्राउज़र उसी डोमेन पर होने के लिए सभी अनुरोधों को पंजीकृत कर रहा है जो हम JSON पोस्ट करने में सक्षम हैं। नोट: यह भी सर्वर पर आयोजित एसएसएल प्रमाणपत्र के साथ काम करता है।


-1

वहाँ (हैक) समाधान मैंने कई बार किया है, आप JsonP के साथ पोस्ट करने में सक्षम होंगे। (आप GET द्वारा उपयोग किए जा सकने वाले 2000 से अधिक बड़े फॉर्म को पोस्ट कर पाएंगे)

ग्राहक आवेदन जावास्क्रिप्ट

$.ajax({
  type: "POST", // you request will be a post request
  data: postData, // javascript object with all my params
  url: COMAPIURL, // my backoffice comunication api url
  dataType: "jsonp", // datatype can be json or jsonp
  success: function(result){
    console.dir(result);
  }
});

जावा:

response.addHeader( "Access-Control-Allow-Origin", "*" ); // open your api to any client 
response.addHeader( "Access-Control-Allow-Methods", "POST" ); // a allow post
response.addHeader( "Access-Control-Max-Age", "1000" ); // time from request to response before timeout

पीएचपी:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');

ऐसा करते हुए, आप अपने सर्वर को किसी भी पोस्ट अनुरोध के लिए खोल रहे हैं, आपको पहचान या कुछ और प्रदान करके इसे फिर से सुरक्षित करना चाहिए।

इस विधि से, आप अनुरोध प्रकार को jsonp से json में बदल सकते हैं, दोनों कार्य, बस सही प्रतिक्रिया सामग्री प्रकार सेट करते हैं

jsonp

response.setContentType( "text/javascript; charset=utf-8" );

json

response.setContentType( "application/json; charset=utf-8" );

कृपया यह न मानें कि आप सर्वर SOP (समान मूल नीति) का अधिक सम्मान नहीं करेंगे, लेकिन कौन परवाह करता है?


यह कोर के साथ AJAX नहीं है। AJAX का अर्थ है कि आप XML का उपयोग कर रहे हैं। यह कॉर्स के साथ JSON [P] है। JSONP "पेडिंग" के साथ "JSON" है। यदि यह JSON डेटा भेज रहा है, तो पेडिंग के लिए एक फ़ंक्शन कॉल के साथ लिपटा हुआ है, तो यह JSONP है CORS के साथ। आप <script>अपने HTML DOM में टैग्स को इंजेक्ट करने के बाहर JSON और JSONP डेटा नोटेशन दोनों का उपयोग कर सकते हैं (बिल्ली आप उन्हें डेस्कटॉप ऐप्स में भी उपयोग कर सकते हैं, कहते हैं कि आप एक ही सर्वर पर कई JSON अनुरोध करना चाहते थे, और फ़ंक्शन नाम का उपयोग करना चाहते थे। उदाहरण के लिए एक अनुरोध ट्रैकिंग आईडी के रूप में)।
BrainSlugs83

-6

यह संभव है, यहाँ मेरा समाधान है:

आपकी जावास्क्रिप्ट में:

jQuery.post("url.php",data).complete(function(data) {
    eval(data.responseText.trim()); 
});
function handleRequest(data){
    ....
}

अपने url.php में:

echo "handleRequest(".$responseData.")";

11
इस स्थिति में jQuery ने आपके दस्तावेज़ के अनुसार आपके अनुरोध को अपने अनुरोध में बदल दिया: नोट: यह दूरस्थ डोमेन अनुरोधों के लिए POST को GET में बदल देगा। api.jquery.com/jQuery.ajax
OneWorld
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.