CORS error in using XMLHttpRequest while using Axios avoid the issue - api

I am just starting to learn how to make requests to APIs using Javascript, and I have been stuck on the following for a few hours.
I used the following public API:
http://www.penguinrandomhouse.biz/webservices/rest/
The issue is that, when I was using XMLHttpRequest, I am always running into an error. At first I didn’t include the content-type in header I got a 404, and when I included it, the error I have got a CORS error.
The following is the code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Request book</title>
<style>
...
</style>
</head>
<body>
<section class="preview">
<div id="return_content"></div>
</section>
<script>
let request = new XMLHttpRequest();
const url = "https://reststop.randomhouse.com/resources/authors";
request.open("GET", url);
let content = {
lastName : "Grisham",
}
request.setRequestHeader('Content-type', 'application/json');
/* I did not add this at first, but it seems like the
default content type for XHR is not what the API wants*/
request.send(JSON.stringify(content));
request.onreadystatechange = () => {
if (this.readyState == 4 && this.status == 200){
console.log(request.responseText);
/* let content_div = document.querySelector('#return_content');
content_div.innerText = request.responseText; */
}
}
</script>
</body>
</html>
The error message is as the following:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://reststop.randomhouse.com/resources/authors. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200
But I tried sending the request first with Axios in node.js with the following, it goes totally fine; so I assume it must be something wrong with my request. However, from my understanding the CORS policy should be set by the server, and it seems like from this post I cannot set Access-Control-Allow-Origin — it is supposed to be something provided by the server-side.
It seems like something is missing in the request but I really have no idea. Any help or hint would be appreciated!

It seems like I didn’t go through all the documents… I kept reading about the API but didn’t go through the CORS MDN page in detail.
Anyway I will just leave it here in case anyone need this in the future.
Quoted from MDN:
For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.
I think this means the CORS policy is a way for the browser to protect itself from malicious scripts too, most likely the ones that aims for the cookies stored in browser.
What I found the most confusing is that the error message changed before and after I added content-type in header. What happened back there, was that I made a “simple request” without knowing it(from this post, the default content type is text-plain), which is why it didn’t trigger the CORS policy but only gave me a 404.

Related

Is there a way to get https version of amazon banner?

I'm trying to show amazon banner on my website. Here's the banner's default code:
<script type="text/javascript" language="javascript">
var aax_size='160x600';
var aax_pubname = 'username';
var aax_src='302';
</script>
<script type="text/javascript" language="javascript" src="http://c.amazon-adsystem.com/aax2/assoc.js"></script>
This is the error I'm getting if I don't change the http link:
first:1 Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but requested an insecure script 'http://c.amazon-adsystem.com/aax2/assoc.js'. This request has been blocked; the content must be served over HTTPS.
Now if I change the url src as https://c.amazon-adsystem.com/aax2/assoc.js. The amazon banner is loading but the padlock is breaking with the following message in the console:
Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure frame 'http://s.amazon-adsystem.com/iu3?d=assoc-amazon.com&rP=https%3A%2F%2Fexample.com'. This request has been blocked; the content must be served over HTTPS.
The above url http://s.amazon-adsystem.com/iu3?d=assoc-amazon.com&rP=https%3A%2F%2Fexample.com is in the javascript hosted by amazon which I can't change. Is there a way to fix it?
Most services which support https but provide http will accept https://our.site.com as an alternative to http://our.site.com. Have you tried just changing the protocol from
"http://s.amazon-adsystem.com/iu3?d=assoc-amazon.com&rP=https%3A%2F%2Fexample.com"
to
"https://s.amazon-adsystem.com/iu3?d=assoc-amazon.com&rP=https%3A%2F%2Fexample.com"
just clear your browser cache or try it in private/incognito window with your HTTPS changes. It can be a browser level issue.
As amazon is using Protocol Relative URL in this script. So there is no where hard coded http or https.
You can view the same by beautifing the code in http://c.amazon-adsystem.com/aax2/assoc.js
By changing http:// to https:// it worked for me.

Shopify API Updating Inventory Levels Not Working

I am trying to update my inventory levels using the Shopify API. I am trying to get it to work using Postman.
I am getting this as a response
<html>
<body>
<noscript>
Continue
</noscript>
<script type="text/javascript">
window.location = "REDACTED";
</script>
</body>
</html>
Your API call is running into issues at API Authentication step. This problem arise, when you are sending cookies with POST request.
From the Shopify documentation,
Shopify prevents HTTP Basic Auth POST requests that have cookies,
which can cause POST calls to fail. If your POST call fails, then you
should try clearing your cookies.
To clear the cookies, use the Cookie manager in Postman app that can be accessed using Cookies button located below the Send and Save buttons.

On Safari, cookies are not saved when sent with redirect

I have implemented an OAuth2 client, in which the first step is to send a user to the relevant 3rd party (facebook for this example), I set them a state cookie, and when they return from facebook I validate that state cookie.
In Chrome, everything is great. When I send the user to the redirect URL, I can see (using inspect element) that they have the state cookie I set.
However, when I try on (desktop) safari on latest MacOS, I don't see that cookie.
I set the cookie in the response for my redirect request:
res.cookie('state', state.toString(), {
maxAge: 3600000,
secure: true,
httpOnly: true,
});
res.redirect(someRedirectUri);
How can I get those cookies to be saved on Safari as well? Am I just setting the cookies wrong?
I think you've found known WebKit issue.
So safari is ignoring the Set-Cookie header when encountering the 302 HTTP status
Late response but I hope this helps anyone else coming across this issue.
I ran into this issue earlier today. It was happening on iOS Safari and Chrome (Chrome on iOS uses WebKit). The workaround I implemented was changing the initial response to a 200 and return a web page which would do a JavaScript redirect in a few seconds.
Here's the HTML I used:
<html lang="en">
<head>
<title>Redirecting...</title>
</head>
<body>
<h1>Redirecting...</h1>
<div>You will be redirected in a moment. If you are not redirected, click the following link: <a id="link" href="https://example.com">Go Now</a></div>
<script type="text/javascript">
var host = "https://"+window.location.host;
document.getElementById("link").setAttribute("href", host);
setTimeout(function(){
window.location.href = host;
}, 3000);
</script>
</body>
</html>
This way the Cookies will be set with the response, and the redirect will happen a moment later.
In my case, I was completing an OAuth workflow. You should be able to customize/render the page in a number of ways to meet other requirements.
I came across this question and the answers when investigating a problem I have with cookies and an OAuth2 client (actually oidc). My problem turned out to be different, so it is not a good answer to the original question, but hopefully it will prevent others reading this from going on a wild goose chase.
I have a backend that sets a session cookie (__ac_session) with information that is used during the authentication with the oidc server. Problems:
At first it looked like this cookie was not saved in the browser, because it was sent in a redirect response. I tried doing the redirect in javascript, from the answer by Padge, but that did not help. Problem was that the cookie was only set on a path (/acl_users/oidc) and both Safari and Chrome did not show this cookie when looking at the homepage. Firefox does show it, but I had unrelated problems with that browser.
So the browser did get the cookie and sent it along with further requests on that path. But the cookie never reached the backend. The problem here was that I had the Varnish caching server in front of the backend, and this removed most cookies, including this one, to improve anonymous caching.
I don't know if you get this with standard Varnish, but with my configuration I did. Relevant part of the final varnish.vcl after I fixed it:
/* cookies for pass */
set req.http.UrlNoQs = regsub(req.url, "\?.*$", "");
if (req.http.Cookie && req.http.Cookie ~ "auth_token|__ac(|_(name|password|persistent|session))=") {
if (req.http.UrlNoQs ~ "\.(js|css|kss)$") {
unset req.http.cookie;
return(pipe);
}
return(pass);
}
My backend is Plone with an oidc plugin. Here is a link to my full issue report, created when I did not yet know the cause.

Getting Rally API key to work outside of rally App

I have seen this question and response, but it still does not work for us:
Embedding Apps with API key
We are having a problem with the Rally API. Our intent is to make a stand-alone page (outside of Rally) that shows the portfolio Kanban.
I have attached the test page. It was created with the rally-app-builder. We created an API key. When we try to load the page, passing the API key, we get a json exception about cross-site violations. The documentation says that we will see this error if we don't pass the key. But even when we do pass it, the error persists.
We have tried it through an apache server, so the issue about being a standalone file is not our problem. Does anyone have any other ideas?
The html page is below.
<!DOCTYPE html>
<html>
<head>
<title>helloworld</title>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/2.0rc3/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function () {
Ext.define("CustomApp",{extend:"Rally.app.App",componentCls:"app",items:{html:'App SDK 2.0rc3 Docs'},launch:function(){this.add({xtype:"rallycardboard",types:["Portfolio Item/Feature"],attribute:"State",storeConfig:{context:{project:"/project/14292239482",projectScopeUp:!1,projectScopeDown:!0}},context:this.getContext(),readOnly:!0})}});
Rally.launchApp('CustomApp', {
name:"helloworld",
parentRepos:""
});
});
</script>
<style type="text/css">
</style>
</head>
<body>
</body>
</html>
The api key we generated is of type alm-wsapi-read-only. When page is loaded, even with apikey parameter provided, we get the JSON x-site error.
We are wondering if there is a config to change on Rally subscription side or perhaps there is an error in the documentation or something else simple.
I submitted a defect. It works up to the point when I load an App-debug.html using rally-app-builder run command:
rab run
and append apiKey to the app's URL as a query parameter. It loads fine using the apiKey:
The problem starts when I choose a different server to load an embedded app, for example:
a)start a simple http python or node server in another directory
b)copy App-external.html from deploy folder to the directory from which the server is running
c)create a new file, App-embedded.html in this directory :
<html>
<header>
<title>Embedded app test: revs</title>
</header>
<body>
<iframe src="http://localhost:9000/App-external.html?apiKey=_Ib4u6d7"></iframe>
</body>
</html>
d)load App-embedded.html
These steps results in cross-origin error.
If you check in Chrome's Network tab, or Safari debugger it shows that artifact (hierarchicalrequirement or defect) requests fails. Interestingly, the preceding subscription, user and schema requests complete successfully. Screenshot from Safari:
It turns out that the underlying issues were related to the CORS configuration on the Rally servers, not anything specific with App SDK 2.0rc3. As of 11/24/14 this issue should be resolved.

neo4j REST API getting HTML response instead of JSON

I'm trying to use neo4j's REST API from an Apache Flex front-end. When my Flex app connects to the base URL (http://localhost:7474/db/data/) to discover other service URLs, it gets replies back in HTML rather than JSON format (just like if I enter the base URL into my browser).
In the Flex HTTP request, I've set the Content-Type and Accept headers both to "application/json" but it hasn't made a difference. I've also tried both GET and POST request methods.
I've verified neo4j is capable of sending JSON responses through a simple telnet window, so it must be "intelligently" formatting the reply based on something in the HTTP request. I'd thought the Content-Type and Accept headers would take care of it, though.
I realize the problem isn't technically in neo4j, but rather somewhere inside Flex's HTTPService (and supporting) classes, but I've been unsuccessful in working around the apparent bug/limitation.
Is there a way to simply force all such responses from neo4j to just be in JSON format?
Thanks,
Chris
* EDIT *
As requested below, here is the exact reply I'm getting in my Flex app:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><title>Root</title><meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<link href='http://resthtml.neo4j.org/style/rest.css' rel='stylesheet' type='text/css'>
<script type='text/javascript' src='/webadmin/htmlbrowse.js'></script>
</head>
<body onload='javascript:neo4jHtmlBrowse.start();' id='root'>
<div id='content'><div id='header'><h1><a title='Neo4j REST interface' href='/'><span>Neo4j REST interface</span></a></h1></div>
<div id='page-body'>
<table class="root"><caption>Root</caption>
<tr class='odd'><th>relationship_index</th><td>http://localhost:7474/db/data/index/relationship</td></tr>
<tr><th>node_index</th><td>http://localhost:7474/db/data/index/node</td></tr>
</table>
<div class='break'> </div></div></div></body></html>
This is the same result I get if I just put the base URL in my web browser manually and retrieve it that way.
I figured it out. When I compiled and ran my Flex app as a browser-based app, it used the browser's native capability to request the URL, blowing away my customized Content-Type and Accept headers.
When I compiled and ran as an Adobe Air desktop app, it worked fine and I received the proper JSON response.
Likely this is a bug in Flash Player, as the documentation for the Flex HTTPService class doesn't give any limitation on changing Content-Type or other headers when running in a browser vs. Air.
-Chris