trying to enable CORS: require is not defined error - javascript

Tl;dr: I'm getting a require is not defined error in the Chrome JS console, despite having installed node.js and requrejs.
I am trying to access API keys in an external JSON file using the following code in main.js:
function readTextFile(file, callback) {
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4 && rawFile.status == "200") {
callback(rawFile.responseText);
}
}
rawFile.send(null);
}
readTextFile("../secrets.json", function(text){
var data = JSON.parse(text);
apiKey = data.api_key;
username = data.username;
});
and since I use an XMLHttpRequest to the API later, which has an http:// scheme, I am looking to use CORS to work around the same-origin policy.
I put these lines at the beginning of main.js:
var cors = require('cors')
var app = express()
app.use(cors());
and my directory structure looks like this:
/project
index.html
secrets.json
/scripts
main.js
require.js
In the JS console on Chrome I get a require is not defined error. Where have I gone wrong?

This code:
var cors = require('cors')
var app = express()
app.use(cors());
Belongs in a node.js server. It is not to be run inside of Chrome. It's purpose is to help you create an http server that can ACCEPT cross origin http requests from a browser.
A browser will only allow a cross origin XMLHttpRequest if the server itself that you are trying to make the request from specifically allows that cross origin request. So, it would be whatever server that supports the URL you are trying to make the XMLHttpRequest to allows cross origin requests (typically by supporting CORS). If the server does not already support your cross origin call, you would have to either modify that server's code or make the request through some sort of proxy that you do have access to that will get the data for you and relay it back to the browser.
Where have I gone wrong?
Well, the require('cors') along with the other two lines of code you show below it are not meant to run in a browser. They run in a node.js environment and would be used to create an http server that you could then connect to from some outside agent (like a browser's web page).
From the browser, you can't do anything to MAKE a server accept cross origin requests if the server isn't already configured to do so. Your only two options are to change the target server or to use a proxy.

require() is NodeJS feature, see the link for more details.
Could You please share the command You start the app?

Related

How to create a live website thumbnail as preview

I'm trying to create a gallery in React with life previews of many websites (like a portfolio) all the linked websites belong to me as well.
I already try to use iFrame and embed but I didn't have the result I would like, I'm trying to get a miniature website like in here https://codesandbox.io/explore.
Even tho the website show the thumbnails as images if you update your sandbox it will the images will update too.
I try use iFrame and embed but it does not show a small version of the website but the website as a mobile and just the frame size.
Any ideas in how I could generate such images or solve this problem in some other way?
You cant do this on the front end in a webpage. You need to execute something like puppeteer on your backend to screenshot the pages. An example can be found on
https://bitsofco.de/using-a-headless-browser-to-capture-page-screenshots/
As of the the same-origin policy, browsers do not allow you to make request to a different domain, you cannot request a different domain from your web app.
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that let servers describe which origins are permitted to read that information from a web browser.
As of an alternative solution you can setup an express server and use cors package to add permission for sending request to your other site.
If you control both sites, then config Cross-Origin Resource Sharing (CORS) from server settings by adding new HTTP headers like Access-Control-Allow-Origin to be accept requests from your other servers
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
const whitelist = ['http://example1.com', 'http://example2.com']
const corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
}
app.listen(4000, function () {
console.log('CORS-enabled web server listening on port 4000')
})
There is also a library that captures screenshot of the given url and save it to the given outputFilePath, capture-website, you can use.

CORS policy error while calling remote URL in Angular

Try to call remote API Url but, getting Access-Control-Allow-Origin error. I tried many things like following but, nothing works.
proxy.conf.js
const PROXY_CONFIG = [
{
context: [
"/api/planets"
],
target: "https://swapi.co",
secure: false,
changeOrigin: true,
logLevel: "debug",
bypass: function (req, res, proxyOptions) {
req.headers["Access-Control-Allow-Origin"] = "*";
req.headers["X-Forwarded-Host"] = "localhost:8090";
req.headers["X-Forwarded-For"] = "localhost";
req.headers["X-Forwarded-Port"] = "8090";
req.headers["X-Forwarded-Proto"] = "http";
}
}
];
module.exports = PROXY_CONFIG;
Running with ng serve --port 8090 --proxy-config proxy.conf.js
Can't make any changes in server side because I am using third party API.
Try adding plugin like https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=en in your chrome browser.
Since you cant change the server side config, so this plugin can do the trick. The browser by default blocks CORS
Since You cannot make any changes on remote server. So it can be escaped using Reverse proxy server. I also faced the same issue while calling linkedin services.
a. There is an https://cors-anywhere.herokuapp.com/ you can append this before your url
and it will temporarily resolve CORS issues.
Since in enterprise scenario you can not use herokuapp.com before your application specific names so better to set below proxy server.
b. Second approach is using rever-proxy approach and set up your own server (local or remote ) for reverse proxying.
https://stackoverflow.com/q/29670703/7562674
You can also implement reverse-proxy like implementation using Spring and Jersey.
https://github.com/hhimanshusharma70/cors-escape
As the error says, a header named Access-Control-Allow-Origin must be present in a CORS response.
Since swapi.co responses include the Access-Control-Allow-Origin header for correct CORS requests (can be tested with a simple fetch('https://swapi.co/api/planets/') from your browser's dev console), the issue may be because of your proxy settings.
Try modifying the response in the proxy bypass method:
bypass: function (req, res, proxyOptions) {
...
// Note that this is "res", not "req".
res.headers["Access-Control-Allow-Origin"] = "*";
...
}
You can't! End of story. If the owner of the api has decided not to allow cross origin requests then you can't. If your are not going to host your app on the https://swapi.co domain then you will not be able to use the api directly from Angular and you will need some kind of pass through api call on the server from .NET, Node, PHP, Java etc.

Api Gateway cannot allow Access-Control-Allow-Origin

This url is in AWS API Gateway with method get and stage is well deployed.
And I enabled CORS following the aws document.
Here are my steps to enable CORS.
-Resource->action->enable CORS->
default setting ->enable CORS and replacing the CORS headers.
There is no error log in CORS result.
I am not a profesional web developer and my browser is safari.
Here is my code to query "http://my.com"
function request(idex) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", "http://my.com", true);
xmlHttp.send(null);}
The console print the error :
XMLHttpRequest cannot load "http://my.com" Origin http://example.com is not allowed by Access-Control-Allow-Origin.
If there are some mistakes in javascript request or in API Gateway deploy?
After consulting and trying each method, I found the error as following.
According to AWS document, we can not deploy our api before enabling CORS. All the settings about the header and CORS must be set before being deployed.
But the API Gateway does not block this setting nor does it show any error dialog. API Gateway will not change the header even if your setting process shows success.
The cross origin problem is from server side not javascript side. When the server does not allow request from other domains it throws cross origin error. But you said you already added CORS in aws instance
As the javascript is only accessing the service from my.com, You need to added proper domain mapping in your my.com site to tell that request will come from another domain called example.com. might be the server is not properly configured. or try if server is expecting any header.
try to see the result in any rest client like soapui, rect client plugin in chrome, etc. once you confirm that there is no problem in server, try it from javascript
To test there is a chrome plugin you can try
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en

Unable to load Angular templates cross-domain with custom headers in requests

we have a project for a client that consists of 3 different websites, and we wanted to re-use as much code as possible. We have one project that contains the bulk of the core Angular JavaScript / templates for directives etc.
We are using ASP.NET 4 and Angular 1.5.5.
I am able to render out a template that's held in Project 1 from Project 2 using the absolute URL with CORS enabled.
However, we are also using a request interceptor for authentication for Single-Sign-On between applications, using the request headers. This stops the cross-domain templates from being pulled over into Project 2 with the following error:
XMLHttpRequest cannot load https://localhost:44302/path/to/template.html. Response for preflight has invalid HTTP status code 405.
If I remove the code that is setting an 'Authorization' header, the template works perfectly cross-domain.
It looks like the only difference in the request with the interceptor is it has the following headers:
access-control-request-headers:authorization
access-control-request-method:GET
Could this be causing the template to not be loaded?
This was solved by setting up CORS in the ASP.NET web side instead of the Angular side.
We enabled it in the Startup.cs file with a private method. We have a Web.config setting called Cors.AllowedOrigins which contains a ; separated string with each application we want to allow in CORS.
private void EnableCors(IAppBuilder app)
{
var policy = new CorsPolicy
{
AllowAnyMethod = true,
AllowAnyHeader = true
};
var origins = ConfigurationManager.AppSettings["Cors.AllowedOrigins"];
if (origins != null)
{
foreach (var origin in origins.Split(';'))
{
policy.Origins.Add(origin);
}
}
else
{
policy.AllowAnyOrigin = true;
}
var corsOptions = new CorsOptions
{
PolicyProvider = new CorsPolicyProvider
{
PolicyResolver = context => Task.FromResult(policy)
}
};
app.UseCors(corsOptions);
}
And we called this in the Configuration method, passing the IAppBuilder.
Adding the header makes the browser make a preflight OPTIONS request, and the server returns a 405 for that OPTIONS request. The browser then aborts the "real" request. Only simple requests can be made without the need of this preflight request. You can only use a limited set of headers to qualify as simple request
If you can serve the template on the same domain and port, it will not be a CORS request and this preflight request will not be made. If not, you can send the correct response to the OPTIONS request using this guide.

Using D3 requests (json) over SSL with path url gives Mixed Content error?

I'm not sure what's going on here - but I thought I'd ask the crowd. Basically I have a fetch JSON data function with D3 that's working on my local development server, but when I move it to production (which is hosted over SSL), I get the following error:
Mixed Content: The page at 'https://myapp.com/' was loaded over HTTPS,
but requested an insecure XMLHttpRequest endpoint 'http://myapp.com/path/to/mydata/'.
This request has been blocked; the content must be served over HTTPS.
It works fine over plain HTTP. The thing is, I'm not specifying a scheme or even an endpoint, I'm just using an absolute path from the root of the web server as follows:
var url = '/path/to/mydata/'
d3.json(url, function(error, data) {
// do something with data
});
Is there anyway I can force this to use SSL? Something similar to "//cdn.com/path/to/asset.js" where the scheme is omitted to allow for both SSL and plain HTTP requests to be made depending on the content of the server.
Updates
More information: I'm hosting this on Heroku, and other requests to my API seem to be working just fine including those using d3.csv and jQuery.get.
Not sure why D3 is insisting on plain http in this case. As a workaround, you could simply detect the protocol and adjust the url accordingly:
var url = window.location.protocol + '//path/to/mydata/'
d3.json(url, function(error, data) {
// do something with data
});

Categories