developer tip

JsonP에 데이터 게시

copycodes 2020. 8. 18. 07:50
반응형

JsonP에 데이터 게시


JsonP에 데이터를 게시 할 수 있습니까? 아니면 모든 데이터가 GET 요청으로 쿼리 문자열에 전달되어야합니까?

서비스, ​​도메인 간 전송해야하는 데이터가 많고 쿼리 문자열을 통해 전송하기에는 너무 큽니다.

이 문제를 해결하기위한 옵션은 무엇입니까?


동일한 출처 정책POST 의 (상당히 합리적인) 제한으로 인해 다른 도메인의 서비스에 대해 비동기를 수행하는 것은 불가능합니다 . JSON-P 는 DOM에 태그 를 삽입 할 수 있고 어디든 가리킬 수 있기 때문에 작동합니다 .<script>

물론 다른 도메인의 페이지를 일반 형식 POST의 작업으로 만들 수 있습니다.

편집 : 숨겨진 s를 삽입 하고 속성을 비웃는 데 많은 노력을 기울이고 싶다면 흥미로운 해킹<iframe>있습니다.


많은 데이터를 도메인 간 전송해야하는 경우. 일반적으로 두 단계로 호출 할 수있는 서비스를 만듭니다.

  1. 먼저 클라이언트는 FORM 제출 (포스트 허용 교차 도메인)을 수행합니다. 서비스는 서버의 세션에 입력을 저장합니다 (GUID를 키로 사용). (클라이언트는 GUID를 생성하고 입력의 일부로 보냅니다)

  2. 그런 다음 클라이언트는 FORM 게시물에서 사용한 것과 동일한 GUID를 사용하는 매개 변수로 일반 스크립트 삽입 (JSONP)을 수행합니다. 서비스는 세션의 입력을 처리하고 일반 JSONP 방식으로 데이터를 반환합니다. 이 후 세션이 파괴됩니다.

물론 이것은 서버 백엔드를 작성하는 것에 달려 있습니다.


나는 이것이 심각한 강령술이라는 것을 알고 있지만 jQuery를 사용하여 JSONP POST 구현을 게시 할 것이라고 생각했는데, 이는 JS 위젯에 성공적으로 사용하고 있습니다 (고객 등록 및 로그인에 사용됨).

기본적으로 수락 된 답변에서 제안한 것처럼 IFrame 접근 방식을 사용하고 있습니다. 내가 다르게하는 것은 요청을 보낸 후 타이머를 사용하여 iframe에서 양식에 도달 할 수 있는지 확인하는 것입니다. 양식에 도달 할 수없는 경우 요청이 반환되었음을 의미합니다. 그런 다음 정상적인 JSONP 요청을 사용하여 작업 상태를 쿼리합니다.

누군가가 유용하다고 생각하기를 바랍니다. > = IE8, Chrome, FireFox 및 Safari에서 테스트되었습니다.

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

Well generally JSONP is implemented by adding a <script> tag to the calling document, such that the URL of the JSONP service is the "src". The browser fetches script source with an HTTP GET transaction.

Now, if your JSONP service is in the same domain as your calling page, then you could probably cobble something together with a simple $.ajax() call. If it's not in the same domain, then I'm not sure how it'd be possible.


You could use a CORS Proxy using this project. It would direct all traffic to an endpoint on your domain and relay that information to an external domain. Since the browser is registering all requests to be on the same domain we are able to post JSON. NOTE: This also works with SSL certificates held on the server.


There's a (hack) solution I've did it many times, you'll be able to Post with JsonP. (You'll be able to Post Form, bigger than 2000 char than you can use by GET)

Client application Javascript

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

JAVA:

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

PHP:

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

Doing like this, you are opening your server to any post request, you should re-secure this by providing ident or something else.

With this method, you could also change the request type from jsonp to json, both work, just set the right response content type

jsonp

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

json

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

Please not that you're server will no more respect the SOP (same origin policy), but who cares ?


It is possible, here is my solution:

In your javascript:

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

In your url.php:

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

참고URL : https://stackoverflow.com/questions/2699277/post-data-to-jsonp

반응형