Cross domain request using jsonp: from https to http - javascript

I have following problem: I need to send some data from page on my site (https://test.com) to another one (for example http://anotherdomain.com). User just enters data to the text box and clicks a button. Script on this page will handle click event and send GET request (using jQuery ajax method) to the http://anotherdomain.com.
var enteredValue = $('#MytextBox').val();
function jsonpCallbackFunc(data)
{
}
$.ajax({
url: 'http://anotherdomain.com/qwerty/ajaxpage.php',
data: { valuefield: enteredValue },
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'jsonpCallbackFunc',
success: function (json) {
// some code
}
})
I received next error using FireFox - "Blocked loading mixed active content http://anotherdomain.com/qwerty/ajaxpage.php...".
The same situation for IE9 and Chrome.
Question: how can we resolve this issue? Can we just allow this script for only one site or maybe we can use another piece of code (not jQuery+jsonp)?
Thank you in advance for the help.
P.S. From "http"-site this code works as expected.
Update:
We resolved the issue using another "https"-url (https://anotherdomain.com/qwerty/ajaxpage.php). We had tried use it before, but it had untrusted certificate. Now it works correctly. Thank you for the help and advice.

This happens due to CORS. When you request to other domain, a preflight request may happen on condition for the ajax calls. You are using jQuery and hence custom header will set in your request. So use
Access-Control-Request-Headers
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Please refer cors and its implementation.

This should also need to be allowed in server, try to add this where you process your request
<?php header('Access-Control-Allow-Origin: *'); ?>
Hope this may help

Related

Mailchimp how to call mailchimp 3.0 API in javascript

I am trying to subscribe an email to a list on mailchimp, I followed the documentation first, made a request using "Postman" added what was needed and everything works just fine, so I tried to do it on my website and it didn't work
I tried to made a simple request with the same values I set on postman, but everytime I try to send the request the response says
XMLHttpRequest cannot load
https://us12.api.mailchimp.com/3.0/lists/xxxxxx/members. Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://mywebsite.com' is therefore not allowed
access. The response had HTTP status code 501.
I tried to find a way to overcome this but it has been impossible
I searched on stackoverflow everybody says to use jsonp or add something to the ajax call or use a mailchimp ajax plugin nothing has worked
I tried diferent stackoverflow posts like this one
Mailchimp subscribe using jQuery AJAX?
but almost all of them say the same
I tried cache: false dataType:jsonp crossDomain: true xhrFields: {withCredentials: true}
Here it is my code, I am using Jquery
$.ajax({
type: "POST",
url: "https://usxx.api.mailchimp.com/3.0/lists/xxxxxxxx/members",
data: { "email_address":email#adress.com, "status":"subscribed"},
headers: {
"Authorization": "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==",
"Content-Type": "application/json"
},
success: function(data){
alert('Thanks for subscribing');
},
error: function(data){
alert('there was an error, try again later');
}
});
I also Thought on creating my own api and then make the call to mailchimp api but I might ran into the same problem
Do you have any suggestions?
Thanks in advance
As charliefl noted, this is a CORS issue. MailChimp doesn't support CORS, mostly because it would require you passing your API credentials to the user of the webpage, allowing them to takeover your entire account.
Your two options for MailChimp are to proxy your requests through a server or, for signing people up to your list, you can build a custom signup form that uses a much more restricted API. The caveat of this second method is that it forces all of your subscribes through MailChimp's double opt-in process.

Chrome shows Access Control Allow Origin error

I'm using jquery to post data to a server, the server received the data, but the chrome still shows the error :
XMLHttpRequest cannot load `myServer:63373/api/sendData`. Origin `myServer:63385` is not allowed by Access-Control-Allow-Origin.
Here is my js code:
$.ajax({
type: 'POST',
url: 'myServer:63373/api/SendData',
crossdomain: true,
async: true,
data: myData,
dataType: 'json',
success: function(){ alert('success'); }
});
The strange thing is that the 'success' shows up after the request, and the server did receive the data, but then the error message shows up in the console. Is there any way to avoid this message?
Thanks for all you answers above but I think I've found the way, before I solve this I was trying to use two ways, Setting Access-Control-Allow-Origin in ASP.Net MVC - simplest possible method
with the 87 votes and 32 votes, I found the answers at two different places, and both applied them, but it didn't work. Early this week, I tried to delete the code in the web.config and just left the code in C#, it works! Can't believe these two solutions have confliction.
Anyway, hope this could help others.
"not allowed by Access-Control-Allow-Origin" is the reason. Put simply, you can't normally do an XHR call to a different domain/port/protocol from those of the webpage your javascript was included into.
Modern browsers allow you work around this with permission from the server administrator.
You make your Ajax request with the XHR2 API (http://www.html5rocks.com/en/tutorials/cors/)
The on the server side, you need to emit the following headers to allow access from the domain that served the page that included your javascript:
Access-Control-Allow-Origin: http://your-page-domain.com
Access-Control-Allow-Credentials: true
if situation are
your script is hosted on another server
or subdomain
or try to hit url with another port
this is cross-domian request. jquery can not fulfill cross-domain request.
if this is your issue , then you should use jsonp for this "jsonp " allows cross domain request.
try to do this with using jsonp.
for jsonp every call has a callback means there will be a value in url
and you have to send respnse with this call back in php
means try this:-
$.ajax({
type: 'POST',
url: 'myServer:63373/api/SendData',
crossdomain: true,
async: true,
data: myData,
dataType: 'jsonp',
success: function(){ alert('success'); }
});
and in php
wrap your response in $_GET['_callback']."(".$response.")"; and echo it
you will get response in json .

Call a external web page (cross-domain) with javascript

I'm trying to validate a feed, using the web service that is in this question.
But browser does not allow me to send a ajax GET request to another server. And there is a one second restriction per each request in that web service, so I can't mirror requests from my server.
This is my current jQuery code:
var reqUrl = "http://validator.w3.org/feed/check.cgi?url=" + encodeURIComponent(theUrl);
$.get(reqUrl, function(data) {
// do something
});
Isn't there any other way?
Ajax calls are not valid across different domains unless you use JSONP. JQuery-ajax-cross-domain is a similar question that may give you some insight. Also as noted by Luis in the comments, JSONP has to also be implemented on the domain that you are getting the data from.
Here is an example for jquery ajax(), but you may want to look into $.getJSON():
$.ajax({
url: 'http://yourUrl?callback=?',
dataType: 'jsonp',
success: processJSON
});
Another option is CORS (Cross Origin Resource Sharing), however, this requires that the other server to enable CORS which most likely will not happen in this case.
I searched google and found this. the third answer says that:
In computing, the same origin policy is an important security concept for a number of browser-side programming languages, such as JavaScript. The policy permits scripts running on pages originating from the same site to access each other's methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites.(source)
you'd better see the answers of this question.
I think you can't use JSONP because you haven't any access to W3C script.
Update (explanations)
I the question I linked to there is another way that I can explain it to you. if you set Access-Control-Allow-Origin header to * as the answer said you can send requests to another domains. and to use it easily in an MVC application you can see this solution. Good luck
Update2
to allow just http://validator.w3.org/ you just should set Access-Control-Allow-Origin to http://validator.w3.org/
for more details as answer said go here.
As said you can use JSONP but the endpoint must also implement it, And its only used if you are requesting json data from the call. It looks like you are retrieving html.
You can also implement a simple proxy in your domain that pulls the data from the external location and serves it to the ajax call. You can develop a simple proxy in php using for instance CURL.
Make sure you understand the implications of this security wise making sure for instance that you protect your proxy to only make calls to that external url (whitelisting).
Update: I just noticed you cannot use the proxy solution. And after following the link you have suggested I have came across CORS, which I didnt event know about. So apparentry you can set some headers when you are serving the pages in your domain that will instruct the browser that requests to some domains can be done.
Check this page for how to implement it:
http://enable-cors.org/
I have read that you might have to tweak it a bit to work with IE but it seems that all browsers are now implementing it.
I know this is an old question, but I myself have been trying to create AJAX requests to validator.w3.org as well, hit the exact same issues and stumbled on this SO question.
However, I did find a solution;
As people have already stated, the main problem here is that the server must issue valid CORS headers, i.e.
Access-Control-Allow-Origin: *
I used Fiddler to check the response headers from validator.w3.org and sure enough, the headers were not set. However, they also have another tool that does at validator.w3.org/nu/.
Here is an example: http://codepen.io/DDN-Shep/pen/ogdGgO/
$('form').on('submit', function(e) {
e.preventDefault();
var data = new FormData(this);
$.ajax({
url: 'http://validator.w3.org/nu/', // Trailing '/' is important or you get a 301 HTTP response status code
type: 'POST',
data: data,
processData: false, // Required for jQuery & FormData
contentType: false, // Set by FormData, required by the server
success: function(data, status, xhr) { /* TODO */ },
error: function(xhr, status, error) { /* TODO */ },
complete: function(xhr, status) { /* TODO */ }
});
});
If you are ever unsure whether or not a server allows CORS, you can use this very helpful online tool;
test-cors.org = http://client.cors-api.appspot.com/client

JSONP communication in a Google Chrome extension

I'm writing a Google Chrome extension. I want to use jsonp cross-domain communication with jQuery. Here is the ajax code:
$.ajax({
type : 'POST',
url : $(this).attr('action'),
data : $(this).serialize(),
contentType: 'application/json; charset=utf-8',
dataType : 'jsonp',
success : function() {
alert('A');
}
});
This calls this URL:
http://sgsync.dev.kreatura.hu/api/signup/?callback=jQuery1710883696963544935_1327347078860&nick=&pass=&_=1327347087371
The server answers 200 OK with this data:
jQuery1710883696963544935_1327347078860({"messages":["Minden mez\u0151 kit\u00f6lt\u00e9se k\u00f6telez\u0151!"],"errorCount":1})
After that, i got this error message:
Can't find variable: jQuery1710883696963544935_1327347078860
I tried everything and i can't understand the problem. Please help me!
Note that i programed the server-side code, so there could be a problem with that too.
Thanks in advance!
Part of the reason this is so confusing is because jQuery API confuses the issue of Ajax calls vs JSONP calls. When using $.ajax with dataType: 'jsonp' this does not do an Ajax call (no XHR communication is used) it instead uses dynamic script injection with a callback. This means that the type: 'POST' will have no meaning (since dynamic script injection only works as a GET would work) and that all of the data will be encoded into the URL of the request as opposed to being send over as a post body. If this is truly intended to "POST" data then JSONP should not be used (since sensitive data will be sent in clear text).
As mentioned in one of the comments, this issue was addressed in this answer with regards to JSONP requests from Chrome content scripts and using XHR from a content script.
JSONP request in chrome extension, callback function doesn't exist?
With regards to Chrome Extensions, they do force you into a sandbox when using the "conten scripts" in a chrome extension. You can remove the dataType: 'jsonp' form the request in the Chrome Extension content script and this call should work. If that does not work, you might trying making the call directly using the XHRHttpRequest:
var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.open("POST", $(this).attr('action'), true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
alert("A");
}
}
xhr.send($(this).serialize());
With regards to other browsers, I am not sure how each of their specific plugin enviroments handle making cross domain XHR calls (or if they even allow it in the first place). This is something that is NOT allowed from normal browsers (unless using something like easyXDM).
Have a look at this question and my answer as I think it might give you a solution...
Auto-load bookmarklet when in webpage as a Google Chrome extension
Basic concepts of JSON-P:
Insert a script tag which loads an external javascript file.
That file does nothing else than execute a pre-defined function, with the data from the server.
How to make it work:
First create a function, bound to the global object (window):
window.processMyData = function processMyData(data) {
console.log(data);
}
Then insert a script tag to the page:script = document.createElement("script");
$('<script></script>')
.prop({'type': 'text/javascript', 'src': 'http://your.url?with=possible&data=in_it'})
.appendTo('body');
You see? No need for the $.ajax wrapper, JSON-P works differently.
Good luck!
Edit: as a response to Duskwuff I would like to add that I don't mean to say $.ajax is bad, or not useful. I am not here to give you a jQuery code snippet, I am trying to let you understand your problem, with the help of a bit more basic javascript / html. JSON-P is not just JSON with a P added, it's completely different from a normal request.

jQuery 1.5 only sends GET requests in ajax method

I am trying to make a PUT request to a RESTful web service, however, it appears that jQuery 1.5 does respond to any changes in the 'type' setting. The request is sent as a GET no matter the value in 'type'. In jQuery 1.4 this isn't a problem.
Here's my code:
$.ajax({
type: "PUT",
url: "https://api.somesite.com/v1.0/people/" + individualID + "/",
dataType: "jsonp",
data: $("#editProfile").serializeArray(),
cache: "false",
success: function(data,textStatus,jqXHR) {
$.modal.close();
},
error: function(jqXHR,textStatus,errorThrown) {
alert("Error!");
}
});
As far as I'm aware, you can't make a JSONP request via PUT. Since JSONP works by injecting a <script> element pointing to the remote domain, that request will always be a GET request.
If you absolutely must make a PUT request to a remote domain, you'll need to either use a server-side proxy on your local domain or look into CORS if you don't need IE support.
From the jQuery.ajax() docs:
The type of request to make ("POST" or
"GET"), default is "GET". Note: Other
HTTP request methods, such as PUT and
DELETE, can also be used here, but
they are not supported by all
browsers.
Perhaps with some additional browser info we can figure out what is causing the problem, but for now it seems jQuery does not want to guarantee functionality except on GET and POST. This is surprising for me to find out =)
How do I PUT data to Rails using JQuery maybe?
edit: oups, you didnt say the webservice was in Rails. But it might support something like that too. Did you try just sending a POST request?
I was struggling with something similar. I have been able to send a PUT successfully pre 1.5 but stopped working with 1.5. I know there was a big change to how the ajax stuff in handled in 1.5 so I'll look into that next.
When it did work it worked fine for me in safari, firefox & chrome. When it works you'll first get an OPTIONS being sent and as pointed out before your server side will have to response satisfactorily to the OPTIONS request a la CORS. Here is a piece ot test code that does work for me pre 1.5 so it is possible. As an aside I was not able to get firefox to cache the OPTIONS response client side. The other browsers did.
http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"
var url = 'http://api.example.com/rest/action?key=123ABC&data={"value":55}';
$.ajax({
type: "PUT",
url: url,
data: {},
success: function(msg){
alert( "Data Saved: " + msg );
},
error: function(msg){
console.debug(msg);
}
});

Categories