For a long time I've being working on how to get access to my WordPress posts. I'm using WP REST API plugin with the WP REST API - OAuth 1.0a Server, and I get an "401 - Only authenticated users can access the REST API" error.
I've read all the documentation and I touched the .htaccess, and I'm going crazy. Please someone help I don't know what to do, and I'm about to give up.
I tried add some code in the .htaccess file, and also tried AJAX and JavaScript fetch, and nothing seems to work. I know there are people using it. It'd be nice someone can tell me how to fix this, I really need it.
jQuery.ajax({
url: 'http://laprensainsolita.com/wp-json/wp/v2/posts',
method: 'GET',
crossDomain: true,
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'Authorization', 'Basic ' + Base64.encode( 'username:password' ) );
},
success: function( data, txtStatus, xhr ) {
console.log( data );
console.log( xhr.status );
}
});
Do I need to add any code to the .htaccess file? And if so what and where should I put it? Or what is need to make this work. I'm very desperate.
The error:
{
"code": "rest_cannot_access",
"message": "Only authenticated users can access the REST API.",
"data": {
"status": 401
}
}
Please try to pass fields to store credentials. Add this fragment to your AJAX call
xhrFields: {
withCredentials: true
},
Your call should look something like this:
Query.ajax({
url: 'http://laprensainsolita.com/wp-json/wp/v2/posts',
method: 'GET',
crossDomain: true,
xhrFields: {
withCredentials: true
},
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'Authorization', 'Basic ' + Base64.encode(
'username:password' ) );
},
success: function( data, txtStatus, xhr ) {
console.log( data );
console.log( xhr.status );
}
});
Related
I have the same call in Meteor HTTP and in jQuery ajax. But the response from server is different.
Meteor:
HTTP.call("POST", url, {
params: data
}, function (error, result) {
//My works....
})
jQuery:
$.ajax({
"url": url,
"method": "POST",
"data": data,
success: function(data_res) {
//My works...
}
})
I would expect the same result, but jquery is executed correctly, while meteor returns an error.
Are calls not identical?
In Meteor method call, Use 'data' field instead of 'params' as it's a POST request.
Try this in Meteor :
HTTP.post( URL, {data:dataToBePosted,headers:{key:value}}//if headers needed use headers field
,function( error, response ) {
if ( error ) {
console.log( error );
} else {
console.log( response);
}
});
I'm having trouble to distinguish an ajax call from other calls in ExpressJS.
As far as I understand, I can use request.accepts('json') to identify a json request?
The problem is - apparently, every call accepts everything!
app.get( '*', function(request, response, next ) {
console.log('request accepts:')
if( request.accepts( 'json' ) ){
console.log( '--> accepts json' )
}
if( request.accepts( 'html' ) ){
console.log( '--> accepts html' )
}
if( request.accepts( 'blah' ) ){
console.log( '--> accepts blah' ) // this does not show up
}
if( request.accepts( 'application/json' ) ){
console.log( '--> accepts json2' )
}
next()
} )
If I just visit the page, it accepts json and html.
If I try to use $.getJSON( ... url ... ), it also acccepts json and html.
Headers:
Browser: "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Ajax: "Accept application/json, text/javascript, */*; q=0.01"
I'm not an expert about the accepts headers, but it seems that the */* part could be the issue.
How can I determine correct (or perhaps, the first) accept type in ExpressJS?
Alternatively: How can I distinguish a JSON request from a normal pagevisit?
Almost all GET requests made by the browser are finished with */*, it means that it accepts pretty much everything. In order to make a decision, you could check req.accepted array. It looks like this:
[ { value: 'application/json',
quality: 1,
type: 'application',
subtype: 'json' },
{ value: 'text/html',
quality: 0.5,
type: 'text',
subtype: 'html' } ]
Thereby, if JSON is present it is a special request, otherwise it is a simple request
I've found a solution that seems to work, by using an array for accepts():
if( request.accepts( [ 'json', 'html' ] ) == 'json' ) {
// do something
} else {
// do something else
}
So I'm working on posting a video to the Emotion API for video and I haven't been able to get a response.
I've been able to get it to work on the Microsoft online console, but when I try to implement it in my Rails app using (1) JavaScript Ajax, or (2) Ruby server-side code, I consistently get various errors.
Here's my code. At first I tried to Ajax way, but I had a suspicion that the API doesn't have CORS enabled. So then I tried Ruby, to no success.
Ruby attempt:
def index
uri = URI('https://api.projectoxford.ai/emotion/v1.0/recognizeinvideo')
uri.query = URI.encode_www_form({
})
data = File.read("./public/mark_zuck.mov")
request = Net::HTTP::Post.new(uri.request_uri)
# Request headers
request['Ocp-Apim-Subscription-Key'] = 'e0ae8aad4c7f4e33b51d776730cff5a9'
# Request body
request.body = data
request.content_type = "video/mov"
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
http.request(request)
end
puts response.body
end
Here's my Ajax attempt:
function CallAPI(apiUrl, apiKey){
console.log("API called");
$(".loading").css("display", "inline-block");
$.ajax({
url: apiUrl,
beforeSend: function (xhrObj) {
xhrObj.setRequestHeader("Content-Type", "application/octet-stream");
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", apiKey);
},
type: "POST",
data: '{"url": "http://localhost:5000/mark_zuck.mov"}',
processData: false,
success: function(response){
console.log("API success");
ProcessResult(response);
$(".loading").css("display", "none");
console.log(response);
},
error: function(error){
console.log("API failed");
$("#response").text(error.getAllResponseHeaders());
$(".loading").css("display", "none");
console.log(error);
}
})
Yes, I've regenerated my key. This is just to illustrate my point.
So you have to set Content-Type to application/octet-stream if it's a binary file you're sending, like I was.
If you use a url you should set Content-Type to application/json and the url must be publicly available.
I am trying to send an Ajax POST request using Jquery but I am having 400 bad request error.
Here is my code:
$.ajax({
type: 'POST',
url: "http://localhost:8080/project/server/rest/subjects",
data: {
"subject:title":"Test Name",
"subject:description":"Creating test subject to check POST method API",
"sub:tags": ["facebook:work", "facebook:likes"],
"sampleSize" : 10,
"values": ["science", "machine-learning"]
},
error: function(e) {
console.log(e);
}
});
It Says: Can not build resource from request.
What am I missing ?
Finally, I got the mistake and the reason was I need to stringify the JSON data I was sending. I have to set the content type and datatype in XHR object.
So the correct version is here:
$.ajax({
type: 'POST',
url: "http://localhost:8080/project/server/rest/subjects",
data: JSON.stringify({
"subject:title":"Test Name",
"subject:description":"Creating test subject to check POST method API",
"sub:tags": ["facebook:work", "facebook:likes"],
"sampleSize" : 10,
"values": ["science", "machine-learning"]
}),
error: function(e) {
console.log(e);
},
dataType: "json",
contentType: "application/json"
});
May be it will help someone else.
In case anyone else runs into this. I have a web site that was working fine on the desktop browser but I was getting 400 errors with Android devices.
It turned out to be the anti forgery token.
$.ajax({
url: "/Cart/AddProduct/",
data: {
__RequestVerificationToken: $("[name='__RequestVerificationToken']").val(),
productId: $(this).data("productcode")
},
The problem was that the .Net controller wasn't set up correctly.
I needed to add the attributes to the controller:
[AllowAnonymous]
[IgnoreAntiforgeryToken]
[DisableCors]
[HttpPost]
public async Task<JsonResult> AddProduct(int productId)
{
The code needs review but for now at least I know what was causing it. 400 error not helpful at all.
Yes. You need to stringify the JSON data orlse 400 bad request error occurs as it cannot identify the data.
400 Bad Request
Bad Request. Your browser sent a request that this server could not
understand.
Plus you need to add content type and datatype as well. If not you will encounter 415 error which says Unsupported Media Type.
415 Unsupported Media Type
Try this.
var newData = {
"subject:title":"Test Name",
"subject:description":"Creating test subject to check POST method API",
"sub:tags": ["facebook:work", "facebook:likes"],
"sampleSize" : 10,
"values": ["science", "machine-learning"]
};
var dataJson = JSON.stringify(newData);
$.ajax({
type: 'POST',
url: "http://localhost:8080/project/server/rest/subjects",
data: dataJson,
error: function(e) {
console.log(e);
},
dataType: "json",
contentType: "application/json"
});
With this way you can modify the data you need with ease. It wont confuse you as it is defined outside the ajax block.
The question is a bit old... but just in case somebody faces the error 400, it may also come from the need to post csrfToken as a parameter to the post request.
You have to get name and value from craft in your template :
<script type="text/javascript">
window.csrfTokenName = "{{ craft.config.csrfTokenName|e('js') }}";
window.csrfTokenValue = "{{ craft.request.csrfToken|e('js') }}";
</script>
and pass them in your request
data: window.csrfTokenName+"="+window.csrfTokenValue
You need to build query from "data" object using the following function
function buildQuery(obj) {
var Result= '';
if(typeof(obj)== 'object') {
jQuery.each(obj, function(key, value) {
Result+= (Result) ? '&' : '';
if(typeof(value)== 'object' && value.length) {
for(var i=0; i<value.length; i++) {
Result+= [key+'[]', encodeURIComponent(value[i])].join('=');
}
} else {
Result+= [key, encodeURIComponent(value)].join('=');
}
});
}
return Result;
}
and then proceed with
var data= {
"subject:title":"Test Name",
"subject:description":"Creating test subject to check POST method API",
"sub:tags": ["facebook:work, facebook:likes"],
"sampleSize" : 10,
"values": ["science", "machine-learning"]
}
$.ajax({
type: 'POST',
url: "http://localhost:8080/project/server/rest/subjects",
data: buildQuery(data),
error: function(e) {
console.log(e);
}
});
I'm hoping this may be of use to those encountering 400 errors while using AJAX in Wordpress going forward. Even though this question is many years old, the solutions provided have all been programmatic, and I'm sure many have stepped through their code to repeatedly find it's correct, yet continue to find it is not working.
I found dozens of results asking how to resolve "WP AJAX request returning 400 Bad Request" or "WP AJAX request returning 0" and nothing today worked.
Googling "How do I fix 400 bad request on Wordpress?" finally resulted in the answer appearing from https://wp-umbrella.com/troubleshooting/400-bad-request-error-on-wordpress/
Clear your Web Browser Cache and Cookies
You may be surprised, but most 400 errors in WordPress can be fixed by clearing your browser's cache and cookies. Browser caches temporarily store images, scripts, and other parts of websites you visit to speed up your browsing experience.
Clearing both my cache and cookies saw the 400 Bad Request code disappear and results return AJAX results as expected.
I have a set of REST URIs that i can access after authenticating on the server. This service takes a JSON input with the login information and retrieve a JSON output with the session ID.
When using a Rest client, like a chrome extension, everything works.
Now I want to implement it using JS but despite of the failure return, I can not see any details of what is wrong (error messages are blank) and neither could found what I am missing in my code.
$.ajax({
// the URL for the request
url: "https://host002:50000/b1s/v1/Login",
// the data to send (will be converted to a query string)
data: {
UserName: "manager",
Password: "1234",
CompanyDB: "CUS_001"
},
// whether this is a POST or GET request
type: "POST",
// the type of data we expect back
dataType : "json",
// code to run if the request succeeds;
// the response is passed to the function
success: function( json ) {
$( "<h1/>" ).text( json.title ).appendTo( "body" );
$( "<div class=\"content\"/>").html( json.html ).appendTo( "body" );
},
// code to run if the request fails; the raw request and
// status codes are passed to the function
error: function( xhr, status, errorThrown ) {
alert( "Sorry, there was a problem! " + xhr.responseText);
console.log( "Error: " + errorThrown );
console.log( "Status: " + status );
console.dir( xhr );
},
// code to run regardless of success or failure
complete: function( xhr, status ) {
alert( "The request is complete!" );
}
});
xhr.responseText is always blank. Status is always error. errorThrown is always blank as well.
I tried also the $post method but got the same behavior.
Your JSON is incorrect. Try using this
data: JSON.stringify({UserName: "manager", Password: "1234", CompanyDB: "CUS_001"});
While navigating from one url to other there is a cross-domain error thing which pops up.
Try doing this.
Call to a function on your same url using ajax and from there use CURL request to your web service url.