Ajax query to ruby server - javascript

I tries to make AJAX request to my ruby server from browser, but server throws this error It is in last string on the screenshot..
When I make request from terminal(python) everything is ok. What I do wrong?
My ruby server
require 'sinatra'
require 'json'
post "/" do
request.body.rewind # in case someone already read it
data = JSON.parse request.body.read
"Hello #{data['name']}!"
end
My ajax query
$.ajax({
url: 'http://127.0.0.1:4567/',
type: 'POST',
contentType: "application/json",
data: {"name":"b"}
})
.done(
function(data){
console.log(data);
}
)

You can add sinatra-cross_origin to your Gemfile.
After that, update your Sinatra app to include and configure the cross_origin settings as follows
require 'sinatra'
require 'json'
require 'sinatra/cross_origin'
configure do
enable :cross_origin
end
before do
response.headers['Access-Control-Allow-Origin'] = '*'
end
options "*" do
response.headers["Allow"] = "GET, PUT, POST, DELETE, OPTIONS"
response.headers["Access-Control-Allow-Headers"] = "Authorization, Content-Type, Accept, X-User-Email, X-Auth-Token"
response.headers["Access-Control-Allow-Origin"] = "*"
200
end
post "/" do
data = JSON.parse request.body.read
"Hello #{data['name']}!"
end
Then you can make your Ajax request like this.
$.ajax({
url: 'http://127.0.0.1:4567/',
type: 'POST',
crossDomain: true,
contentType: "application/json",
data: '{"name":"b"}',
})
.done(
function(data){
console.log(data);
}
)
The difference here is adding crossDomain: true.
Putting these two together should log the right stuff after the Ajax call.
Note: Here we've added Access-Control-Allow-Origin="*". If you know where your html is deployed and where the server sits, you may prefer to have that set to something specific so that it can't be accessed by any site. If your html is deployed at myapp.whateverdomain.com and you might want your server to have something more like
response.headers["Access-Control-Allow-Origin"] = "https://myapp.whateverdomain.com"
You can read more about CORS configuration here

Related

Getting parse error while fetching text file content in JQuery

I am trying to fetch data from text file which resides on server. I have access of that location and able to see content when I put URL in browser tab.
I am trying to make AJAX call and get file content, but I am getting Error: Uncaught SyntaxError: Unexpected identifier
Code
function logResults(json){
console.log(json);
}
$.ajax({
url: u,
dataType: "jsonp",
jsonpCallback: "logResults"
});
on console,
I tried below code too, but same result,
$.ajax({
type: 'GET',
url: u,
crossDomain: true,
dataType: 'jsonp',
async: false,
headers: {
"Access-Control-Allow-Origin": "*"
},
success: function(succ) {
console.log("Success: ", succ)
},
error: function(err) {
console.log("Error: ", err)
}
});
This code is always going into error block.
You said:
dataType: "jsonp",
But the URL is responding with:
Deployment automatically finished…
Which is not JSONP, it is plain text.
You get the error when it tries to execute the plain text as JSONP.
Don't put wrong information in the dataType field.
async: false,
That's deprecated. Don't use it. It's also pointless since you are using callbacks.
It's also incompatible with JSONP so it is ignored (until you remove the incorrect dataType).
crossDomain: true,
This has no effect unless you are making a:
non-JSONP request
to the same origin
which gets redirected to a different origin
… which is very rare.
headers: {
"Access-Control-Allow-Origin": "*"
},
Access-Control-Allow-Origin is a response header. It doesn't belong the request. Trying to add it to the request will cause extra problems as it will make the request preflighted.
(At least, that would be the case if you hadn't said dataType: 'jsonp' because adding request headers is incompatible with JSONP).
All you need on the client
The only code you need on the client is:
function logResults(result){
console.log(result);
}
$.ajax({
url: u,
success: logResults
});
The server you are requesting the data from will need to use CORS to grant you permission to access it if it is a cross-origin request.
It is because you have added dataType as jsonp, so that it will try to parse the response to JSON and if the response is not a JSON it will throw error.

in Ajax, how to write "headers" for multiple condition?

as a beginner, I have some problems in using Ajax (with Discogs API) .. to get a discogs request token, discogs is saying
Include the following headers with your request:
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="your_consumer_key",
oauth_nonce="random_string_or_timestamp",
oauth_signature="your_consumer_secret&",
oauth_signature_method="PLAINTEXT",
oauth_timestamp="current_timestamp",
oauth_callback="your_callback"
User-Agent: some_user_agent
https://www.discogs.com/developers#page:authentication,header:authentication-discogs-auth-flow
but, how to write this header?
below is my trying code, but I know this is not proper.
$.ajax({
type: "GET",
url: "https://api.discogs.com/oauth/request_token",
dataType: 'jsonp',
headers: {
ContentType: "application/x-www-form-urlencoded",
Authorization: OAuth oauth_consumer_key="your_consumer_key",
oauth_nonce="random_string_or_timestamp",
oauth_signature="your_consumer_secret&",
oauth_signature_method="PLAINTEXT",
oauth_timestamp="current_timestamp",
oauth_callback="your_callback",
UserAgent: some_user_agent,
}
success: function (data) {
console.log(data);
document.getElementById("content").innerHTML += "<br>" + `${data}`;
},
error: function (error) {
console.log(error);
}
});
You said:
dataType: 'jsonp',
It isn't possible to specify headers for JSONP requests.
The API can't be using JSONP. Set the dataType to the format they are using.
The documentation says:
When you create a new application, you’ll be granted a Consumer Key and Consumer Secret, which you can plug into your application and start making authenticated requests. It’s important that you don’t disclose the Consumer Secret to anyone.
Putting those in your client-side code will disclose them to all your visitors.
The request to that end point should be made from server-side code.

JSON POST on iOS with Flask

Inside my flask python web program, I save a few parameters in SessionStorage in order to send them back to flask, then save this information as a txt file.
For some reason, everything works flawlessly on PC and Android, couldn't get it to work on iOS devices. it recognizes and saves the sessionStorgae elements before sending, but no txt file is created afterwards (at the end of the app).
Client-side (HTML):
function func()
{
...
$.ajax({
url: "{{ url_for('getInfo', _external=True) }}",
type: 'POST',
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
success: function (response) {
console.log(response);
},
accepts: {
json: 'application/json',
},
data: JSON.stringify(log)
});
return;
...
}
<form id = "myForm" name ="myForm" method="post" action="{{url_for('final')}}" onsubmit="return func()">
Server-side (Flask):
#app.route("/get_info",methods = ['POST'])
def getInfo():
list = request.get_json()
global id
with open(id + '.txt', 'w+') as outfile:
json.dump(list,outfile,indent=2)
return 'OK'
I can't figure out the solution. Also I can't remember if it used to work or not on iOS. trying to run all kinds of tests as I'm writing this. Any help would be much appreciated. Thanks.
If you believe more information is needed, I elaborated in the comments about the overall structure of that HTML page and web program.
Your code in 'DEBUG' mode
#app.route("/get_info",methods = ['POST'])
def getInfo():
list = request.get_json()
global id
file_name = '{}.txt'.format(id)
print('About to write {} to file {}'.format(str(list),file_name))
with open(file_name, 'w+') as outfile:
json.dump(list,outfile,indent=2)
print('Data was written')
return 'OK'
Found an answer for future readers:
iOS puts ajax request in cache. which later on might give empty response, or don't trigger the function at all. you can solve that by adding a few parameters and headers to the ajax request, which will prevent it from happenning:
cache: false,
processData: false,
async: true,
headers: {
"cache-control": "no-cache"
},

How to make a jsonp POST request that specifies contentType with jQuery?

I need to make a jsonp POST request with the content type 'application/json'. I can get the POST request to the server like this:
jQuery.ajax({
type: 'POST',
url: url,
data: data,
success: success,
error: error,
async: true,
complete: complete,
timeout: TIMEOUT,
scriptCharset: 'UTF-8',
dataType: 'jsonp',
jsonp: '_jsonp',
});
But as soon as I add the line:contentType: "application/json" it starts sending it as an OPTIONS request rather than a POST.
How can I specify the content type and still submit the request as a POST?
It is not possible to make a JSONP POST request.
JSONP works by creating a <script> tag that executes Javascript from a different domain; it is not possible to send a POST request using a <script> tag.
Use json in dataType and send like this:
$.ajax({
url: "your url which return json",
type: "POST",
crossDomain: true,
data: data,
dataType: "json",
success:function(result){
alert(JSON.stringify(result));
},
error:function(xhr,status,error){
alert(status);
}
});
and put this lines in your server side file:
if PHP:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');
if java:
response.addHeader( "Access-Control-Allow-Origin", "*" );
response.addHeader( "Access-Control-Allow-Methods", "POST" );
response.addHeader( "Access-Control-Max-Age", "1000" );
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 ?

Ajax call to different website returns html instead of an array

I'm trying to receive an array using an .ajax GET request to a URL.
Here's my controller, hosted locally on localhost:3000
def merchant_ids
merchants = Merchant.where(id: params[:id]).pluck(:merchant_name, :id, :merchant_city, :physical_address, :merchant_phone, :latitude, :longitude)
render json: merchants
end
If I make a request the following way:
$.ajax('http://localhost:3000/dashboard/merchants/merchant_ids/1').done(function(data) { console.log(data); });
it logs the array just fine.
But if I try to do the same thing from another app using localhost:3001 it returns
the whole html view instead of the array.
what am I doing wrong here?
I have gem 'rack-cors' and the config:
config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
allow do
origins '*'
resource '/*', :headers => :any, :methods => [:get, :post]
end
end
In your Ajax call try putting ContentType and dataType as json
try this-
$.ajax({
url:"http://localhost:3000/dashboard/merchants/merchant_ids/1",
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(function(data) { console.log(data); });
Because you are trying to access the json data on callback, you need to specify the dataType of the returned data .. Also specify this along with your ajax request..
dataType: "json",

Categories

Resources