Javascript 将数据发布到 JsonP
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2699277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Post data to JsonP
提问by ChrisCa
Is it possible to post data to JsonP? Or does all data have to be passed in the querystring as a GET request?
是否可以将数据发布到 JsonP?还是所有数据都必须作为 GET 请求在查询字符串中传递?
I have alot of data that I need to send to the service, cross domain, and it is too large to send via the querystring
我有很多数据需要发送到服务,跨域,而且太大而无法通过查询字符串发送
What are the options for getting around this?
解决这个问题有哪些选择?
采纳答案by friedo
It is not possible to do an asynchronous POSTto a service on another domain, due to the (quite sensible) limitation of the same origin policy. JSON-P only works because you're allowed to insert <script>tags into the DOM, and they can point anywhere.
POST由于同源策略的(非常明智的)限制,不可能对另一个域上的服务执行异步操作。JSON-P 之所以有效,是因为您可以将<script>标签插入到 DOM 中,并且它们可以指向任何地方。
You can, of course, make a page on another domain the action of a regular form POST.
当然,您可以使另一个域上的页面成为常规表单 POST 的操作。
Edit: There are some interesting hacksout there if you're willing to go to a lot of effort inserting hidden <iframe>s and mucking about with their properties.
编辑:如果您愿意付出大量努力插入隐藏的s 并处理它们的属性,那么有一些有趣的技巧<iframe>。
回答by Per
If you need to send a lot of data cross-domain. I usually create a service that you can call in two steps:
如果需要跨域发送大量数据。我通常会创建一个服务,您可以分两步调用该服务:
First the client do a FORM submit (post allowed cross domain). The service stores the input in the session on the server (using the GUID as key). (the client creates a GUID and send's it as a part of the input)
Then the client do a normal script-inject (JSONP) as a parameter you use the same GUID as you used in the FORM post. The service processes the input from the session and returns the data in the normal JSONP-fashion. After this the session is destroyed.
首先客户端做一个 FORM 提交(允许跨域发布)。该服务将输入存储在服务器上的会话中(使用 GUID 作为键)。(客户端创建一个 GUID 并将其作为输入的一部分发送)
然后客户端执行正常的脚本注入 (JSONP) 作为参数,您使用与 FORM 帖子中使用的 GUID 相同的 GUID。该服务处理来自会话的输入并以正常的 JSONP 方式返回数据。在此之后,会话被销毁。
This of course relies on that you write the server-backend.
这当然取决于您编写服务器后端。
回答by W.B.
I know this is serious necromancy, but I thought I'd post my implementation of JSONP POST using jQuery, which I'm successfully using for my JS widget (this is used for customer registration and login):
我知道这是严重的死灵法术,但我想我会使用 jQuery 发布我的 JSONP POST 实现,我已成功将其用于我的 JS 小部件(用于客户注册和登录):
Basically, I'm using an IFrame approach, as suggested in the accepted answer. What I'm doing differently is after sending the request, I'm watchin, if the form can be reached in the iframe, using a timer. When the form cannot be reached, it means the request has returned. Then, I'm using a normal JSONP request to query for the status of the operation.
基本上,我使用的是 IFrame 方法,如已接受的答案中所建议。我正在做的不同之处是在发送请求后,我正在观察,如果可以使用计时器在 iframe 中访问表单。当无法访问表单时,表示请求已返回。然后,我使用一个普通的 JSONP 请求来查询操作的状态。
I hope that someone finds it useful. Tested in >=IE8, Chrome, FireFox and Safari.
我希望有人觉得它有用。在 >=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;
}
回答by Pointy
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.
通常JSONP是通过<script>在调用文档中添加一个标签来实现的,这样JSONP服务的URL就是“src”。浏览器通过 HTTP GET 事务获取脚本源。
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.
现在,如果您的 JSONP 服务与您的调用页面在同一个域中,那么您可能可以通过一个简单的$.ajax()调用拼凑一些东西。如果它不在同一个域中,那么我不确定这怎么可能。
回答by Eugene Scray
You could use a CORS Proxyusing 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.
您可以使用此项目使用CORS 代理。它会将所有流量定向到您域上的端点并将该信息中继到外部域。由于浏览器将所有请求注册到同一个域中,我们可以发布 JSON。 注意:这也适用于服务器上保存的 SSL 证书。
回答by Dimitri Kopriwa
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)
有一个(hack)解决方案我已经做过很多次了,你将能够使用 JsonP 发布。(您将能够发布表单,大于 2000 个字符,您可以通过 GET 使用)
Client application Javascript
客户端应用程序 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:
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.
这样做,您正在向任何发布请求打开您的服务器,您应该通过提供 ident 或其他东西来重新保护它。
With this method, you could also change the request type from jsonp to json, both work, just set the right response content type
使用这个方法,你也可以将请求类型从 jsonp 改为 json,都可以,只要设置正确的响应内容类型
jsonp
jsonp
response.setContentType( "text/javascript; charset=utf-8" );
json
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 ?
请注意,您的服务器将不再遵守 SOP(同源政策),但谁在乎呢?
回答by nosemaj
It is possible, here is my solution:
这是可能的,这是我的解决方案:
In your javascript:
在你的 javascript 中:
jQuery.post("url.php",data).complete(function(data) {
eval(data.responseText.trim());
});
function handleRequest(data){
....
}
In your url.php:
在你的 url.php 中:
echo "handleRequest(".$responseData.")";

