I'm currently developing a web application using JavaScript which the web app will create a new playlist then save it to user's Spotify account. Now, I'm facing the issue of "Error Parsing JSON" whenever I tried POST request. Below is my code:
var urlString = 'https://api.spotify.com/v1/users/' + userID + '/playlists';
app.createPlaylist = (urlString) => $.ajax({
url: urlString,
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken
},
contentType: 'application/json',
body: JSON.stringify({
name: "test",
public: true
}),
dataType: 'json',
});
Can anyone tell me what's the problem? I've tried surfing this website, and none of the possible answers to my question helped my situation.
Related
I am a jQuery/Ajax newbie. I have a web app written in Java.
I want to use jQuery/Ajax to send JSON data to my controller. The endpoint for the controller is secured. Therefore, authentication is required for the POST request.
My problem is I don't know how I get the username and password to send in the Ajax headers without using any input form?
So far I have manually inserted a user into the headers and this works fine.
What I want is:
if the user is already logged in, send their credentials in the headers, and
if the user is not logged redirect the user to the login page, and if successful post the JSON to the database.
My code so far:
<script type="text/javascript">
function send() {
const time = new Date($.now());
var json = {
"time": time.toISOString,
"name": ui.Data.name,
"address": uiData.address,
}
$.ajax({
type: 'POST',
url: 'http://localhost:8080/users/profile/save',
data: JSON.stringify(json),
headers: {
"content-type": "application/json",
"accept": "application/json",
"cache-control": "no-cache",
"authorization": "Basic " + btoa("john" + ":" + "12345"),
},
success: function(data) {
alert(data)
}
});
return false;
};
I am trying to add records to CRM using Javascript but getting:
401 Unauthorized Error.
My question is how to get the token and use it inside the JavaScript function.
$(document).ready(function() {
$("#Save").click(function() {
var ProductDetails = new Object();
ProductDetails.ProductName = $("#txt_productName").val();
ProductDetails.ProductDetail = $("#txt_desc").val();
$.ajax({
url: "https://mycrm.dynamics.com/api/data/v9.1/Products",
type: "Post",
dataType: 'JSON',
data: ProductDetails,
contentType: 'application/x-www-form-urlencoded',
success: function(data) {
alert('Updated Successfully');
},
error: function(request, status, error) {
alert(request.status);
}
});
});
});
You need add Authorization information in Http Header. Here is an example if you use JWT.
$(document).ready(function() {
$("#Save").click(function() {
var ProductDetails = new Object();
ProductDetails.ProductName = $("#txt_productName").val();
ProductDetails.ProductDetail = $("#txt_desc").val();
$.ajax({
url: "https://mycrm.dynamics.com/api/data/v9.1/Products",
type: "Post",
headers: {
'Accept':'application/json',
'Content-Type':'application/json',
'Authorization':'Bearer your token here'
},
dataType: 'JSON',
data: ProductDetails,
contentType: 'application/x-www-form-urlencoded',
success: function(data) {
alert('Updated Successfully');
},
error: function(request, status, error) {
alert(request.status);
}
});
});
});
You have to add a header with the bearer token like this:
$.ajax({
(...)
headers: {
"Authorization": "Bearer " + token
},
(...)
In order to get a token you have to register an application in Azure Active Directory first, in the same tenant as your Dynamics 365 instance. Check this link if you need a thorough step by step guide to do it.
After registering you application in AAD you also have to add some code to do the authentication with Azure and getting the token. ADAL.js does this job for you, but keep in mind that it prompts the user to manually add his username and password in a office 365 popup. This is called interactive authentication and as far as I know it can't be avoided.
For a full HTML + JS working example click here.
I was trying to make an audio player by starting with a play button. In my HTMl code i made a button:
Play
Then I used this code to make it play a song, but it doesnt seem to work.
document.getElementById('play').addEventListener('click', function() {
$.ajax({
url: 'https://api.spotify.com/v1/me/player/play',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
},
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"uris": ["spotify:track:"] + apiData.item.id,
"position_ms": apiData.progress_ms
})
});
});
apiData.item.id refers to the id of the currently playing track
apiData.progress_ms refers to the progress in milliseconds of currently playing track.
When I run my code and click on the play button, nothing happens. I don't know what I did wrong.
But I tried making a pause button by first making a button with an id called 'pause'. Then I did the following:
document.getElementById('pause').addEventListener('click', function() {
$.ajax({
url: 'https://api.spotify.com/v1/me/player/pause',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
},
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"uris": ["spotify:track:"] + apiData.item.id,
"position_ms": apiData.progress_ms
})
});
});
This is actually working! But I don't understand why the play button doesn't work and the pause button does.
Here is the documentation I used for both buttons:
https://developer.spotify.com/documentation/web-api/reference/player/start-a-users-playback/
https://developer.spotify.com/documentation/web-api/reference/player/pause-a-users-playback/
For the play button I got this error in the console log:
error 400
Can somebody help me out?
tl;dr: Working snippets at the bottom of this answer!
The uris field takes an array containing Spotify uris. This "uris": ["spotify:track:"] + apiData.item.id doesn't resolve to an array but to a string which is not what the endpoint awaits. Using [`spotify:track:${id}`] will work therefore.
This snippet shows the difference between the two.
console.log(["spotify:track:"] + id);
// Output with id = 1234: "spotify:track:1234" -> String
console.log([`spotify:track:${id}`]);
// Output with id = 1234: ["spotify:track:1234"] -> Array of strings
The reason the stop button works is that Spotify's pause endpoint doesn't use any of the data you passed in. The pause endpoint only has one optional query parameter called device_id. The data you passed along with it just gets ignored therefore. So the Ajax call for pause can be simplified as seen in the following snippets.
Here are two working snippets given that an access token is used that has the user-modify-playback-state scope authorized.
Play
$.ajax({
url: 'https://api.spotify.com/v1/me/player/play',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
},
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
"uris": [`spotify:track:${apiData.item.id}`],
"position_ms": apiData.progress_ms
})
});
Pause
$.ajax({
url: 'https://api.spotify.com/v1/me/player/pause',
type: 'PUT',
headers: {
'Authorization': 'Bearer ' + access_token
}
});
My question is very simple and I thought creating this program would only take a couple hours. However now I have been working on it all day trying to figure out what I could be doing wrong.
All I am trying to do is post messages to slack using their postMessage api. I have been able to send messages succesfully using slacks testing methods.
This is the url that is outputted by the test
https://slack.com/api/chat.postMessage?token=xoxp-xxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxxxxx&channel=XXXXXXXX&text=Just%20need%20the%20url&as_user=jheuman&pretty=1
I then decided to try it out locally using this html file served from my file system
<!DOCTYPE html>
<html>
<head>
<title>Testing Slack API</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<button onClick="test()">Test</button>
<button onClick="test2()">Authorization Test</button>
<script>
function test() {
var apiUrl = "https://slack.com/api/chat.postMessage";
var token = "xoxp-xxxxx...";//my token has been omitted for security;
var channel = "#general";
var text = "Testing slack api";
var user = "jheuman";
var actualToken = "Bearer " + token;
$.ajax({
headers: {
'Authorization':actualToken,
'Content-Type':'application/json'
},
data: JSON.stringify({
"channel": channel,
"text": text,
"as_user": user
}),
dataType: 'json',
processData: false,
type: 'POST',
url: apiUrl
})
.done(function(data) {
console.log(JSON.stringify(data));
})
.fail(function(response) {
console.log(JSON.stringify(response));
});
};
function test2() {
var apiUrl = "https://slack.com/api/auth.test";
var token = "xoxp-xxxxx..."; //my token has been omitted for security
var channel = "#general";
var text = "Testing slack api";
var user = "jheuman";
var actualToken = "Bearer" + token;
$.ajax({
headers: {
'Authorization':actualToken
},
type: 'POST',
url: apiUrl,
})
.done(function(data) {
console.log(JSON.stringify(data));
})
.fail(function(response) {
console.log(JSON.stringify(response));
});
};
</script>
But when I click either button I get the following error:
Failed to load https://slack.com/api/chat.postMessage: Request header field
Authorization is not allowed by Access-Control-Allow-Headers in preflight
response.
So per a friends Suggestion I tried it out on a server. I used Web Server For Chrome to serve it up on port 8887. First without setting cors headers and then with setting cors headers. Both to no avail. I received the same error.
As you can see I also tried the auth.test call but I receive the same error.
Slack specifically states that they prefer an authorization header and that the api can handle json data.
Other things I have tried:
Having no header field with token in data:
data: JSON.stringify({
'token':actualToken,
'channel': channel,
'text': text,
'as_user': user
}),
dataType: 'json',
processData: false,
type: 'POST',
url: apiUrl
Errors received:
{"ok":false,"error":"invalid_form_data"}
Having no header field with token in data without 'Bearer':
data: JSON.stringify({
'token':token,
'channel': channel,
'text': text,
'as_user': user
}),
dataType: 'json',
processData: false,
type: 'POST',
url: apiUrl
Errors received:
{"ok":false,"error":"invalid_form_data"}
Things I have looked into but don't think will effect outcome
The type of token
So how do I get this post request to work?
I am not set on jquery or ajax, it is just what I have used in the past so if you have a different request library to use I'm all ears.
If you need more information I will try to give it to you
Since configuring CORS correctly for sending data with content-type application/json can be tricky, I would suggest to send the request as application/x-www-form-urlencoded which is the default for AJAX.
Example:
var apiUrl = "https://slack.com/api/chat.postMessage";
var token = MY_TOKEN;
var channel = "general";
var text = "Testing slack api";
var user = "jheuman";
$.ajax({
data: {
"token": token,
"channel": channel,
"text": text,
"as_user": user
},
dataType: 'text',
type: 'POST',
url: apiUrl,
error: function(xhr,status,error){
console.log("error: " + error);
},
success: function(data) {
console.log("result: " + data);
}
});
In case you get CORS errors, you can add crossDomain: true
This solution is tested and works when run in a normal browser.
You need to reply to that CORS preflight with the appropriate CORS headers to make this work. One of which is indeed Access-Control-Allow-Headers. That header needs to contain the same values the Access-Control-Request-Headers header contained (or more).
https://fetch.spec.whatwg.org/#http-cors-protocol explains this setup in more detail.
headers: {
'Authorization':actualToken,
'Content-Type':'application/json',
'Access-Control-Allow-Headers':'x-requested-with'
},
to get SharePoint List dataI am having an issue accessing the REST server via the CSOM. I have tried this with both the CSOM and just using jQuery. Code examples and the associated errors below. Can anyone direct me to a working example or tell me what I am doing wrong?
This code is part of a SharePoint Hosted App and the list is just a list in the root web. The user has permission to access the list and the app.
CSOM Example:
Yields:
Fail! : App Web is not deployed for this app's request url http://mySharePointRootWebURL.local.
var data = new SP.RequestExecutor("http://mySharePointRootWebURL.local/");
data.executeAsync({
method: "GET",
headers: { "Accept": "application/json;odata=verbose" },
url: "http://mySharePointRootWebURL.local/_api/web/lists/getbytitle(\'MyLstName\')/items",
success: function (data) { console.log('success!'); },
error: function (p1,p2,errorMessage) { console.log('Fail! :' + errorMessage); }
});
I can see that this example is not hitting the root web at all (from the app / app web).
jQuery Example
Yields:
Resource interpreted as Script but transferred with MIME type text/plain: "http://mySharePointRootWebURL.local/_api/web/lists/getbytitle(\'MyLstName\')/items&…Query19104068602353800088_1379462071044&alt=json-in-script&_=1379462071045". jquery.js:9597
Uncaught SyntaxError: Unexpected token < items:1
fail! : Error: jQuery19104068602353800088_1379462071044 was not called
$.ajax({
url: "http://mySharePointRootWebURL.local/_api/web/lists/getbytitle(\'MyListName\')/items",
type: "GET",
beforeSend: function(xhr){
xhr.setRequestHeader('Accept', 'application/json;odata=verbose'); },
headers: {"Accept":"application/json;odata=verbose"},
success: function(data){ console.log("success"); },
error: function errHandler(p1,p2,errMessage){ console.log("fail! : " + errMessage); },
dataType: 'jsonp',
crossDomain: true,
data: {
alt: 'json-in-script'
},
});
This is working as far as accessing the REST server and returning data, the problem is that the headers are not being added at all (verified in Fiddler). Without the headers the data comes back in XML. If that's how it has to be I will work with it, I guess, but I'd prefer to get JSON.
Your code doesn't look right. Here's code that wors with the cross-domain library
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url:
appweburl +
"/_api/SP.AppContextSite(#target)/web/lists/getByTitle('Contacts')/items" +
"?#target='" + hostweburl + "'" +
"&$select=Id,FirstName,Title,WorkPhone,Email" +
"&$orderby=Title,FirstName",
method: "GET",
headers: { "accept": "application/json;odata=verbose" },
success: successHandler,
error: errorHandler
})