Cross-origin request blocked when using AJAX - javascript

Hey I just installed script on same host, twice, just different accounts.
The scripts worked fine, but for random reason, one of them started to drop all AJAX requests, and print the following messsage in Mozilla:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.yoursite.com/vote/ajax/xmlhttp/claim. This can be fixed by moving the resource to the same domain or enabling CORS.
When I access the link directly, works fine, but with AJAX it just fails.. on the other account (host account) it works fine so far.
On my VPS and pc it works fine.
In PHP error log, it prints undefined variables, which is not really possible, how can AJAX affect this, especially in this random situation, where it works and sometimes now on this host.
My JS:
var reward = $("#rewards ul li");
var selected = [];
var limit = <?php echo $limit; ?>;
var errors = $(".error");
var timeout;
console.log(limit);
$("#claim").click(function() {
$("#claim").text('Checking...');
if ($("#username").val() == "") {
$("#claim").text('Claim my reward(s) now');
showError("Fill in your in-game username.");
return;
}
if (selected.length == limit) {
$.ajax({
type: "POST",
url: "<?php echo $post_url; ?>",
data: {username: $("#username").val(), rewards: JSON.stringify(selected)},
success: function(data) {
$("#claim").text('Claim my reward(s) now');
if (data.substr(0, 6) == 'error:') {
showError(data.substr(6));
}
else {
$("#claim").text('Success!');
$(".section").html(data);
}
}
});
}
else {
showError("You must select " + limit + " rewards(s) to continue.");
}
});
Let me know if you need the functions I used too.
What is causing this problem?
I tried adding the following response:
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
But it's bad because it will still have undefined variables in it, and still process the response which will cause JavaScript syntax errors.
Thanks in advice.

if i understood you right you are trying to pass data between to different servers;
the answer to this is JSONP, it works like JSON but should pass that CORS problem.
to do so you need to change a little bit your php code and ajax code.
in php you need to wrap the JSON data in a callback and in AJAX you need to define - dataType: "jsonp", read more about jsonp here: What is JSONP all about?.
it worked for me!

Related

Request to Google Apps Script URL for deployed WebApp produces 404 error

This issue is very similar to others (like Google Drive Page Not Found - Sorry, unable to open the file at this time for example) posted here. It's not exactly the same, but I do believe it has the same root issue illustrated in that post in that trying to submit a form to a Google App Script while logged into more than to 1 Google account causes /u/1 and/or /u/0 to be added to the script's URL thus producing a 404 Error.
This is using a standard Google account - not G-Suite.
I have a form on a website that submits to a Google Apps Script via AJAX. The script makes some API calls to create a Google Doc containing the data collected by the form.
HTML/Javascript:
<form>
<input type="text" name="full_name">
<input type="text" name="phone">
<input type="submit">
</form>
$('form').submit(function() {
var obj = $(this).serializeObject();
var gurl = "https://script.google.com/macros/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec";
$.ajax({
url: gurl,
type: "GET",
data: obj,
dataType: "jsonp",
success: function(data, status, xhr) {
console.log("success");
console.log(data);
});
});
GoogleScripts
function doGet(e) {
var params = e.parameters
var result = {};
try {
result = {
status: start(params),
msg: 'Success',
vals: formData,
rawVals: params,
errs: errors
}
} catch (f) {
result.error = f.toString();
}
return ContentService
.createTextOutput(e.parameters.callback + '(' + JSON.stringify(result) + ')')
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Submitting the form while logged into more than 1 Google account in the same browser results in the following error in the console and the form does nothing:
jquery.js?ver=1.12.4-wp:4 GET
https://script.google.com/macros/u/1/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec?callback=jQuery112407830193282901534_1608623376571&s&full_name=Dave+Pe&phone=1111111111_=1608623376572
net::ERR_ABORTED 404
When I go to Network tab to view the request, the Header tab there shows the following:
Request URL: https://script.google.com/macros/u/1/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec?callback=jQuery112407830193282901534_1608623376571&s&full_name=Dave+Pe&phone=1111111111_=1608623376572
Notice the /u/1/ that have been inserted into the URL that are not present in the URL I pass to my $.ajax() call.
Most of the answers I've found for this issue say to just remove the /u/1/, but since I didn't add it in the 1st place, I don't know where I would remove it from.
Can anyone confirm that this seemingly known issue (of having the URL altered when logged into multiple Google accounts) is what is causing my problems? Any ideas as to how I can go about making my request to:
https://script.google.com/macros/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec
and not
https://script.google.com/macros/u/1/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec
?? or is there something more deeply wrong with the way I'm trying to use Google Scripts here?
My solution was to move the request from the client side to the server. I submit my form values to a server-side page via AJAX and then on that page, I make an HTTP request with cURL to my Google Apps Script (sending the form data in the body) and send the response back to the client.
Seems to be working... no issues I can think of but that doesn't mean they don't exist. If there are any holes to be shot in that approach, please feel free to unload.
Watered down...
JavaScript
$.ajax({
url: '/ajax-handler.php',
type: "POST",
data: obj
success: function(data, status, xhr) {
console.log("success");
console.log(data);
});
});
PHP
$vals = my_sanitize_func($_POST);
$url = GAS_URL;
$fields = $vals;
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($fields));
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
// handle/format response;
$result = ...
print $result;
You can also do whatever you want this way.
Google App Script (Code.gs):
function doGet(e){
var action = e.parameter.action;
if (action=="sendSuccess"){
justSendSuccess(e);
}
}
function justSendSuccess(e){
var output = JSON.stringify({"result":"success"});
return ContentService
.createTextOutput(e.parameter.callback+"("+ output + ");")
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
JavaScript Part:
function callGoogleScript(){
console.log("Started");
var url = "https://script.google.com/macros/s/###SCRIPT_ID###/exec";
$.ajax({
crossDomain: true,
url: url,
data: {
"action":"setInfo"
},
method: "GET",
dataType: 'jsonp',
jsonp: "callback",
success: function(data){
console.log("SUCCESS!");
console.log(data);
}
});
}
I tried to run it (authenticated with a single account) and it seems to work. This error seems to happen because you are authenticated with multiple accounts. Also, it seems as it has already been documented at Google Issue Tracker (link to issue). If you want it to make it more visible, you can click the white star (☆) which tells google that you are affected by this issue.
As a side note, notice that the code you make will be executed by everyone as you. This code will have your privileges. Be very careful. Your account limits may also apply.

browser adding some number to url

I am trying to get xml through ajax like below in my javascript code
$(document).ready(function(){
$.ajax({
url: 'https://santander.easycruit.com/intranet/intranett/export/xml/vacancy/list.xml',
cache: false,
dataType: 'xml',
crossDomain: true,
success: function (xml) {
debugger;
$(xml).find('Vacancy').each(function () {
$(this).find("Location").each(function () {
var name = $(this).text();
alert(name);
});
});
},
statusCode: {
404: function () {
debugger;
alert('Failed');
}
}
});
});
but when i run code i get error XMLHttpRequest cannot load https://santander.easycruit.com/intranet/intranett/export/xml/vacancy/list.xml?_=1460979186038. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mymachinename' is therefore not allowed access
You can see there is some number appended to url like _=1460979186038
Is it because of this i am getting error.
The _=1460979186038 part is added by jquery ajax, as the mechanism to prevent cache. If I remember currectly that number is just a random + timestamp or something like that.
source: http://api.jquery.com/jquery.ajax/
The reason you are getting the error is No 'Access-Control-Allow-Origin' header is present on the requested resource, which means you are trying to send cross-domain messages but the server didn't allow it.
It's clearly that you are facing with the issue with cross domain request.
If you can control this server, you will need add the header in your server to allow cross domain or for testing purpose, you can use my add on in firefox to development and deal with CORS: https://addons.mozilla.org/en-US/firefox/addon/cross-domain-cors/?src=ss
Based on comments discussion I think you should make something like proxy server. Try this PHP code:
<?php
header("Content-type: text/xml");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://santander.easycruit.com/intranet/intranett/export/xml/vacancy/list.xml");
$output = curl_exec($ch);
It would simply fetch desired XML from passed URL and display it on the page.
Put the script on the same server your javascript is and call your server with ajax. This should eliminate CORS limitations.

Get json ajax php form to work remotely

So, essentially I have this Javascript which interprets the JSON from my php code. It works great on the local server, however, when I try to move the script to a different server it will not work. I have added the
<?php header("Access-Control-Allow-Origin: *"); ?>
also i've declared my database connection as global within my PHP function.
I'm confused as to why these solutions aren't working.. Also, I understand some of the script is iffy, but I'm only interested in figuring out why its not working from different servers.
<script type="text/javascript">
$("document").ready(function(){
$(".sendText").submit(function(){
$("#sendButton").prop("disabled",true);
$(".errors").html("");
$(".success").html("");
var data = {
"action": "test"
};
data = $(this).serialize() + "&" + $.param(data);
$.ajax({
type: "POST",
dataType: "jsonp", //new edit
url: "http://myurl.com/testing/jsonpost.php?callback=test", //new edit
data: data,
success: function(data) {
if(data["success"]=="yes") {
$(".success").html("Message Sent!");
$(".formContainer").html("" + data["json"] + "");
}
else {
if(document.getElementById("sendButton").disabled = true){ document.getElementById("sendButton").disabled = false; }
$(".errors").html("" + data["errors"] + "");
}
}
});
return false;
});
});
</script>
Some Info when I look at the web console from firebug:
Access-Control-Allow-Orig... *
Connection Keep-Alive
Content-Length 0
Content-Type application/json
Date Wed, 24 Sep 2014 04:22:57 GMT
Keep-Alive timeout=5, max=100
Server Apache/2.2.27 (Unix) mod_ssl/2.2.27 OpenSSL/1.0.1e-fips DAV/2 mod_bwlimited/1.4
X-Powered-By PHP/5.4.29
Looks like it is communicating with server but not able to interpret data? thoughts?
Also, this error comes up in the console from the remote server but not when I run on local server:
SyntaxError {stack: (...), message: "Unexpected end of input"}message: "Unexpected end of input"stack: (...)
Object {readyState: 4, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…
parsererror
The PHP code is pretty long (and I prefer not to release all of it) - however here is the shortened version:
<?php
header("Access-Control-Allow-Origin: *");
header('Content-Type: application/json');
require "../database/db.php";
if (is_ajax()) {
if (isset($_POST["action"]) && !empty($_POST["action"])) { //Checks if action value exists
$action = $_POST["action"];
switch($action) { //Switch case for value of action
case "test": test_function(); break;
}
}
}
//Function to check if the request is an AJAX request
function is_ajax() {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}
function test_function(){
$c="1";
global $con;
$return = $_POST; //to reference post
$content=$return["content"];
//see if content is 140 characters or less
if(strlen($content)>140){ $c="0"; $lerror="<li>Your message must be 140 characters or less in length!</li>"; }
if($c=="0"){ //doesnt pass validation
$return["success"]="no";
$return["errors"]="$lerror";
}
if($c!="0"){ //passes validation
$return["success"]="yes";
}
if(isset($_GET['callback'])){ //jsonp edit
$return["json"] = json_encode($return);
echo $_GET['callback']."(".json_encode($return).")"; //jsonp edit
}
}
Also after converting to JSONP on remote server - get error -
"jQuery111006159528985153884_1411663761720 was not called"
When dealing with jQuery AJAX using a data type of JSON, any notice, warning or error produced by the server side script will cause issues. The reason being is the outputted PHP errors break the JSON encoding that jQuery is expecting.
I suspect the two environments are not identical, perhaps a different PHP version, missing PHP extension or different settings in the php.ini file.
The best thing to do is to use the provided jQuery AJAX error callback to console log any errors allowing you to essentially troubleshoot any issues being thrown by the server side script.
!!! EDIT 3 !!!
Client Code
$.ajax({
type: "POST",
dataType: "json",
url: "http://myurl.com/jsonpost.php",
data: data,
success: function(response) {
console.log(response);
},
error: function(xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
}
});
Server Side Code
header("Access-Control-Allow-Origin: *");
header('Content-Type: application/json');
echo json_encode(array('success' => 'yes'));
Using this bare bones version of your code I can successfully make a cross domain request and console log the response. If you implement this code and it still does not work there is something else at play at the server and/or network level.
You can make AJAX calls to a backend API, it needs to return JSONP format and not just JSON, otherwise you can get error. This is due to same origin policy:
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.
This discussion may be helpful to understand JSONP:
Can anyone explain what JSONP is, in layman terms?
However, one alternative is disable the security of Google Chrome browser, then it will work. But this is not a solution. It is better to use JSonP format.

Phonegap - Fetch External Website Data?

I am creating an app using Phonegap (Android) and Javascript / JQuery. I have a Javascript page where I want to read in the text from an external web page. For some reason I am not able to get this to work.
My Javascript page within my app
$.mobile.allowCrossDomainPages = true;
$(document).ready(function () {
$.ajax({
url: 'myexternalserver.com/test.php',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data, status){
alert("connected");
},
error: function(){
alert("jsonp error");
}
});
});
My PHP page on external server
// $out is an array of text
echo $_GET['jsoncallback'] . '(' . json_encode($out) . ');';
I modified my Cordova.xml file to include
<access origin="http://myexternalserver.com" subdomains="true"/>
Am I missing any other steps? I always get a connection error.
Thanks.
EDIT:
I have modified my javascript page to the following
$.getJSON("http://myexternalserver.com/test.php?var=test&callback=?", {
success:function(data){
alert("Working");
var ot = jQuery.parseJSON( data );
alert(ot);
}, error: function() {
alert("Error");
}
});
I now get the "working" alert but the data reads as null.
Make sure that your server is returning proper headers. I had similar problem with phonegap application until my server returned following headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Max-Age: 1728000
Access-Control-Allow-Headers: *
You can read more about it at https://developer.mozilla.org/en/http_access_control
Also check out http://api.jquery.com/jQuery.support attribute cors
To enable cross-domain requests in environments that do not support cors yet but do allow cross-domain XHR requests (windows gadget, etc), set $.support.cors = true;
As already said, confirm if you're getting any response whether success or error from the server, I use the developer tools in Chrome for that.
If you're however using the default index.html file generated when you created the app, check for, and allow 'myexternalserver.com' in the rule for the "Content Security Policy" (CSP) in addition to your current setup.

How do I send a cross-domain POST request via JavaScript?

How do I send a cross-domain POST request via JavaScript?
Notes - it shouldn't refresh the page, and I need to grab and parse the response afterwards.
Update: Before continuing everyone should read and understand the web.dev tutorial on CORS. It is easy to understand and very clear.
If you control the server being POSTed, simply leverage the "Cross-Origin Resource Sharing standard" by setting response headers on the server. This answer is discussed in other answers in this thread, but not very clearly in my opinion.
In short here is how you accomplish the cross domain POST from from.com/1.html to to.com/postHere.php (using PHP as an example). Note: you only need to set Access-Control-Allow-Origin for NON OPTIONS requests - this example always sets all headers for a smaller code snippet.
In postHere.php setup the following:
switch ($_SERVER['HTTP_ORIGIN']) {
case 'http://from.com': case 'https://from.com':
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
break;
}
This allows your script to make cross domain POST, GET and OPTIONS. This will become clear as you continue to read...
Setup your cross domain POST from JS (jQuery example):
$.ajax({
type: 'POST',
url: 'https://to.com/postHere.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
When you do the POST in step 2, your browser will send a "OPTIONS" method to the server. This is a "sniff" by the browser to see if the server is cool with you POSTing to it. The server responds with an "Access-Control-Allow-Origin" telling the browser its OK to POST|GET|ORIGIN if request originated from "http://from.com" or "https://from.com". Since the server is OK with it, the browser will make a 2nd request (this time a POST). It is good practice to have your client set the content type it is sending - so you'll need to allow that as well.
MDN has a great write-up about HTTP access control, that goes into detail of how the entire flow works. According to their docs, it should "work in browsers that support cross-site XMLHttpRequest". This is a bit misleading however, as I THINK only modern browsers allow cross domain POST. I have only verified this works with safari,chrome,FF 3.6.
Keep in mind the following if you do this:
Your server will have to handle 2 requests per operation
You will have to think about the security implications. Be careful before doing something like 'Access-Control-Allow-Origin: *'
This wont work on mobile browsers. In my experience they do not allow cross domain POST at all. I've tested android, iPad, iPhone
There is a pretty big bug in FF < 3.6 where if the server returns a non 400 response code AND there is a response body (validation errors for example), FF 3.6 wont get the response body. This is a huge pain in the ass, since you cant use good REST practices. See bug here (its filed under jQuery, but my guess is its a FF bug - seems to be fixed in FF4).
Always return the headers above, not just on OPTION requests. FF needs it in the response from the POST.
If you control the remote server, you should probably use CORS, as described in this answer; it's supported in IE8 and up, and all recent versions of FF, GC, and Safari. (But in IE8 and 9, CORS won't allow you to send cookies in the request.)
So, if you don't control the remote server, or if you have to support IE7, or if you need cookies and you have to support IE8/9, you'll probably want to use an iframe technique.
Create an iframe with a unique name. (iframes use a global namespace for the entire browser, so pick a name that no other website will use.)
Construct a form with hidden inputs, targeting the iframe.
Submit the form.
Here's sample code; I tested it on IE6, IE7, IE8, IE9, FF4, GC11, S5.
function crossDomainPost() {
// Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString;
// construct a form with hidden inputs, targeting the iframe
var form = document.createElement("form");
form.target = uniqueString;
form.action = "http://INSERT_YOUR_URL_HERE";
form.method = "POST";
// repeat for each parameter
var input = document.createElement("input");
input.type = "hidden";
input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
Beware! You won't be able to directly read the response of the POST, since the iframe exists on a separate domain. Frames aren't allowed to communicate with each other from different domains; this is the same-origin policy.
If you control the remote server but you can't use CORS (e.g. because you're on IE8/IE9 and you need to use cookies), there are ways to work around the same-origin policy, for example by using window.postMessage and/or one of a number of libraries allowing you to send cross-domain cross-frame messages in older browsers:
Porthole
XSSInterface
EasyXDM
jQuery PostMessage Plugin
If you don't control the remote server, then you can't read the response of the POST, period. It would cause security problems otherwise.
Create an iFrame,
put a form in it with Hidden inputs,
set the form's action to the URL,
Add iframe to document
submit the form
Pseudocode
var ifr = document.createElement('iframe');
var frm = document.createElement('form');
frm.setAttribute("action", "yoururl");
frm.setAttribute("method", "post");
// create hidden inputs, add them
// not shown, but similar (create, setAttribute, appendChild)
ifr.appendChild(frm);
document.body.appendChild(ifr);
frm.submit();
You probably want to style the iframe, to be hidden and absolutely positioned. Not sure cross site posting will be allowed by the browser, but if so, this is how to do it.
Keep it simple:
cross-domain POST:
use crossDomain: true,
shouldn't refresh the page:
No, it will not refresh the page as the success or error async callback will be called when the server send back the response.
Example script:
$.ajax({
type: "POST",
url: "http://www.yoururl.com/",
crossDomain: true,
data: 'param1=value1&param2=value2',
success: function (data) {
// do something with server response data
},
error: function (err) {
// handle your error logic here
}
});
If you have access to all servers involved, put the following in the header of the reply for the page being requested in the other domain:
PHP:
header('Access-Control-Allow-Origin: *');
For example, in Drupal's xmlrpc.php code you would do this:
function xmlrpc_server_output($xml) {
$xml = '<?xml version="1.0"?>'."\n". $xml;
header('Connection: close');
header('Content-Length: '. strlen($xml));
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/x-www-form-urlencoded');
header('Date: '. date('r'));
// $xml = str_replace("\n", " ", $xml);
echo $xml;
exit;
}
This probably creates a security problem, and you should make sure that you take the appropriate measures to verify the request.
Check the post_method function in http://taiyolab.com/mbtweet/scripts/twitterapi_call.js - a good example for the iframe method described above.
Create two hidden iframes (add "display: none;" to the css style). Make your second iframe point to something on your own domain.
Create a hidden form, set its method to "post" with target = your first iframe, and optionally set enctype to "multipart/form-data" (I'm thinking you want to do POST because you want to send multipart data like pictures?)
When ready, make the form submit() the POST.
If you can get the other domain to return javascript that will do Cross-Domain Communication With Iframes (http://softwareas.com/cross-domain-communication-with-iframes) then you are in luck, and you can capture the response as well.
Of course, if you want to use your server as a proxy, you can avoid all this. Simply submit the form to your own server, which will proxy the request to the other server (assuming the other server isn't set up to notice IP discrepancies), get the response, and return whatever you like.
One more important thing to note!!!
In example above it's described how to use
$.ajax({
type : 'POST',
dataType : 'json',
url : 'another-remote-server',
...
});
JQuery 1.6 and lower has a bug with cross-domain XHR.
According to Firebug no requests except OPTIONS were sent. No POST. At all.
Spent 5 hours testing/tuning my code. Adding a lot of headers on the remote server (script). Without any effect.
But later, I've updated JQuery lib to 1.6.4, and everything works like a charm.
If you want to do this in ASP.net MVC environment with JQuery AJAX, follow these steps:
(this is a summary of the solution offered at this thread)
Assume that "caller.com"(can be any website) needs to post to "server.com"(an ASP.net MVC application)
On the "server.com" app's Web.config add the following section:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
</customHeaders>
</httpProtocol>
On the "server.com", we'll have the following action on the controller(called "Home") to which we will be posting:
[HttpPost]
public JsonResult Save()
{
//Handle the post data...
return Json(
new
{
IsSuccess = true
});
}
Then from the "caller.com", post data from a form(with the html id "formId") to "server.com" as follow:
$.ajax({
type: "POST",
url: "http://www.server.com/home/save",
dataType: 'json',
crossDomain: true,
data: $(formId).serialize(),
success: function (jsonResult) {
//do what ever with the reply
},
error: function (jqXHR, textStatus) {
//handle error
}
});
There is one more way (using html5 feature). You can use proxy iframe hosted on that other domain, you send message using postMessage to that iframe, then that iframe can do POST request (on same domain) and postMessage back with reposnse to the parent window.
parent on sender.com
var win = $('iframe')[0].contentWindow
function get(event) {
if (event.origin === "http://reciver.com") {
// event.data is response from POST
}
}
if (window.addEventListener){
addEventListener("message", get, false)
} else {
attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");
iframe on reciver.com
function listener(event) {
if (event.origin === "http://sender.com") {
var data = JSON.parse(event.data);
$.post(data.url, data.data, function(reponse) {
window.parent.postMessage(reponse, "*");
});
}
}
// don't know if we can use jQuery here
if (window.addEventListener){
addEventListener("message", listener, false)
} else {
attachEvent("onmessage", listener)
}
High level.... You need to have a cname setup on your server so that other-serve.your-server.com points to other-server.com.
Your page dynamically creates an invisible iframe, which acts as your transport to other-server.com. You then have to communicate via JS from your page to the other-server.com and have call backs that return the data back to your page.
Possible but requires coordination from your-server.com and other-server.com
I think the best way is to use XMLHttpRequest (e.g. $.ajax(), $.post() in jQuery) with one of Cross-Origin Resource Sharing polyfills https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#wiki-CORS
This is an old question, but some new technology might help someone out.
If you have administrative access to the other server then you can use the opensource Forge project to accomplish your cross-domain POST. Forge provides a cross-domain JavaScript XmlHttpRequest wrapper that takes advantage of Flash's raw socket API. The POST can even be done over TLS.
The reason you need administrative access to the server you are POSTing to is because you must provide a cross-domain policy that permits access from your domain.
http://github.com/digitalbazaar/forge
I know this is an old question, but I wanted to share my approach. I use cURL as a proxy, very easy and consistent. Create a php page called submit.php, and add the following code:
<?
function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));
Then, in your js (jQuery here):
$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
Should be possible with a YQL custom table + JS XHR, take a look at:
http://developer.yahoo.com/yql/guide/index.html
I use it to do some client side (js) html scraping, works fine
(I have a full audio player, with search on internet/playlists/lyrics/last fm informations, all client js + YQL)
CORS is for you.
CORS is "Cross Origin Resource Sharing", is a way to send cross domain request.Now the XMLHttpRequest2 and Fetch API both support CORS, and it can send both POST and GET request
But it has its limits.Server need to specific claim the Access-Control-Allow-Origin, and it can not be set to '*'.
And if you want any origin can send request to you, you need JSONP (also need to set Access-Control-Allow-Origin, but can be '*')
For lots of request way if you don't know how to choice, I think you need a full functional component to do that.Let me introduce a simple component https://github.com/Joker-Jelly/catta
If you are using modern browser (> IE9, Chrome, FF, Edge, etc.), Very Recommend you to use a simple but beauty component https://github.com/Joker-Jelly/catta.It have no dependence, Less than 3KB, and it support Fetch, AJAX and JSONP with same deadly sample syntax and options.
catta('./data/simple.json').then(function (res) {
console.log(res);
});
It also it support all the way to import to your project, like ES6 module, CommonJS and even <script> in HTML.
If you have access to the cross domain server and don't want to make any code changes on server side, you can use a library called - 'xdomain'.
How it works:
Step 1:
server 1: include the xdomain library and configure the cross domain as a slave:
<script src="js/xdomain.min.js" slave="https://crossdomain_server/proxy.html"></script>
Step 2:
on cross domain server, create a proxy.html file and include server 1 as a master:
proxy.html:
<!DOCTYPE HTML>
<script src="js/xdomain.min.js"></script>
<script>
xdomain.masters({
"https://server1" : '*'
});
</script>
Step 3:
Now, you can make an AJAX call to the proxy.html as endpoint from server1. This is bypass the CORS request. The library internally uses iframe solution which works with Credentials and all possible methods: GET, POST etc.
Query ajax code:
$.ajax({
url: 'https://crossdomain_server/proxy.html',
type: "POST",
data: JSON.stringify(_data),
dataType: "json",
contentType: "application/json; charset=utf-8"
})
.done(_success)
.fail(_failed)

Categories

Resources