Can't load trained model with Tensorflow.js - javascript

my model (tf.keras.Sequential) was trained in Python, and I converted it into TF.js Layers format by using tfjs.converters.save_keras_model().
I created a server in folder (which contains *.bin files and a 'model.json'), using 'http-server' in cmd.
After that, I run this code to load the model:
(async () => {
const model = await tf.loadLayersModel('http://127.0.0.1:8080/model.json');
console.log('done');
})();
It doesn't work for me, these 3 errors appear in my console:
Access to fetch at 'http://127.0.0.1:8080/model.json' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
GET http://127.0.0.1:8080/model.json net::ERR_FAILED
Uncaught (in promise) Error: Request for http://127.0.0.1:8080/model.json failed due to error: TypeError: Failed to fetch
at tf.min.js:2
I have no idea how to fix it.

So this is an issue with CORS (Cross Origin Resource Sharing) - you need more than just simple web server to serve the files.
For any static files (like the bin and json files you have) that you want to use across domains on website etc you need to set the right header for those files by the web server so the browser knows its ok to use on such sites.
This is to do with web security across domains and whilst it catches a lot of folk out its important to have. Not sure what web server you are running but if you are using Express with Node.js then check this simple tutorial:
https://enable-cors.org/server_expressjs.html
or this lib:
https://medium.com/#alexishevia/using-cors-in-express-cac7e29b005b
Note the Allow-Origin part which is where you need to set the domain you plan to use it on. You can also use wildcard * to allow all domains if you want anyone to be able to use use those files on their sites too without issue.
Oh and fun fact, if you dont want to deal with a web server at all try Glitch.com which allows you to host experimental projects and upload assets if this is just for fun - it sets all the CORS headers correctly and is easy to use and prototype stuff on. https://glitch.com/#TensorFlowJS

Related

How to fix the "No 'Access-Control-Allow-Origin'" error for a solution deployed in production?

I have a VueJS(+quasar) frontend that is using two backend developed by myself.
The backend are not in the same domain.
The backend's domain are :
https://user-backend.net (manage user and application rights)
https://data-backend.net (contains all my business data)
And the frontend's domain is :
https://myapp.net
I use Axios as an API reader, both backend gives api's endpoint.
So I had the AXIOS cors problem when I was on dev mode (localhost with different ports) So to get around the problem I ran my browser without the web safeties, as it was only development.
However, today I put the application in production and I have this error again.
So I looked for several solutions on the Internet and each time I was offered the same step to work around.
So I followed one of them and here is what I put:
axios.js
export default boot(async ({ app }) => {
axios.defaults.headers.common["Access-Control-Allow-Origin"] =
"*";
});
But now, here it is, for a development environment I think it's not a problem but now that I'm in production, how can I fix this problem?
I'm really bothered with these CORS POLICY and I'd like to fix this problem with the most optimized way for production.
Here is the console log error :
Access to XMLHttpRequest at 'https://user-backend.net/tokens' from origin 'https://myapp.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is CORS error not SOP, so this is not related to the front-end, backed must set Access-Control-Allow-Origin : * // or your domain for more security

How to solve 'Redirect has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header'?

I am working on an app using Vue js.
According to my setting I need to pass to a variable to my URL when setting change.
<!-- language: lang-js -->
$.get('http://172.16.1.157:8002/firstcolumn/' + c1v + '/' + c1b, function (data) {
// some code...
});
But when my app hit on URL, it shows the following message.
Failed to load http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26: Redirect from 'http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26' to 'http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
In addition to what awd mentioned about getting the person responsible for the server to reconfigure (an impractical solution for local development) I use a change-origin chrome plugin like this:
Moesif Orign & CORS Changer (use to be free but now wants a work email address >_>)
Allow CORS: Access-Control-Allow-Origin
You can make your local dev server (ex: localhost:8080) to appear to be coming from 172.16.1.157:8002 or any other domain.
In case the 2nd plugin link breaks in the future or the plugin writer decides to capitalize off the fame of this thread, open your browser's
plugin marketplace and search "allow cors", there's going to be a
bunch of them.
Thanks all, I solved by this extension on chrome.
Allow CORS: Access-Control-Allow-Origin
If you have control over your server, you can use PHP:
<?PHP
header('Access-Control-Allow-Origin: *');
?>
Ask the person maintaining the server at http://172.16.1.157:8002/ to add your hostname to Access-Control-Allow-Origin hosts, the server should return a header similar to the following with the response-
Access-Control-Allow-Origin: yourhostname:port
Using npm:
To allow cross-origin requests install 'cors':
npm i cors
Add this in the server-side:
let cors = require("cors");
app.use(cors());
When you have this problem with Chrome, you don't need an Extension.
Start Chrome from the Console:
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
Maybe you have to close all Tabs in Chrome and restart it.
I will assume that you're a front-end developer only and that you don't have access to the backend of the application (regarding the tags of the question).
Short answer on how to properly solve this in your case? You can't, you'll need somebody else.
What is this about?
You need to understand that CORS is a security thing, it's not just here to annoy you just for fun.
It's purpose is to mainly prevent the usage of a (malicious) HTTP call from a non-whitelisted frontend to your backend with some critical mutation.
You could give a look to this YouTube video or any other one really, but I recommend a visual video because text-based explanation can be quite hard to understand.
You also need to understand that if you use Postman or any other tool to try your API call, you will not get the CORS issue. The reason being that those tools are not Web frontends but rather some server-based tools.
Hence, don't be surprised if something is working there but not in your Vue app, the context is different.
Now, how to solve this?
Depending of the framework used by your backend team, the syntax may be quite different but overall, you'll need to tell them to provide something like Access-Control-Allow-Origin: http://localhost:3000 (or any other port you'll be using).
PS: Using Access-Control-Allow-Origin: * would be quite risky because it would allow anybody to access it, hence why a stricter rule is recommended.
If you're using a service, like an API to send SMS, payment, some Google console or something else really, you'll need to allow your localhost in the dashboard of the service. Ask for credentials to your manager or Tech Lead.
If you have access to the backend, you could it yourself as shown here (ExpressJS in this example): https://flaviocopes.com/cors/
How to hack it in a dirty way?
If you're in a damn hurry and want to get something really dirty, you could use a lot of various hacks a listed in the other answers, here's a quick list:
use any extension who is able to create a middleware and forward the request to the backend (it will work because it's not directly coming from your frontend)
force your browser to disable CORS, not sure how this would actually solve the issue
use a proxy, if you're using Nuxt2, #nuxtjs/proxy is a popular one but any kind of proxy (even a real backend will do the job)
any other hack related somehow to the 3 listed above...
At the end, solving the CORS issue can be done quite fast and easily. You only need to communicate with your team or find something on your side (if you have access to the backend/admin dashboard of some service).
I heavily do recommend trying get it right from the beginning because it's related to security and that it may be forgotten down the road...
The approved answer to this question is not valid.
You need to set headers on your server-side code
app.use((req,res,next)=>{
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,PATCH,DELETE');
res.setHeader('Access-Control-Allow-Methods','Content-Type','Authorization');
next();
})
You can also try a chrome extension to add these headers automatically.
Hello If I understood it right you are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
When you are using postman they are not restricted by this policy. Quoted from Cross-Origin XMLHttpRequest:
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
To add the CORS authorization to the header using Apache, simply add the following line inside either the <Directory>, <Location>, <Files> or <VirtualHost> sections of your server config (usually located in a *.conf file, such as httpd.conf or apache.conf), or within a .htaccess file:
Header set Access-Control-Allow-Origin "*"
And then restart apache.
Altering headers requires the use of mod_headers. Mod_headers is enabled by default in Apache, however, you may want to ensure it's enabled.
I had the same problem in my Vue.js and SpringBoot projects. If somebody work with spring you can add this code:
#Bean
public FilterRegistrationBean simpleCorsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// *** URL below needs to match the Vue client URL and port ***
config.setAllowedOrigins(Collections.singletonList("http://localhost:8080"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
I found solution in this article Build a Simple CRUD App with Spring Boot and Vue.js
You are making a request to external domain 172.16.1.157:8002/ from your local development server that is why it is giving cross origin exception.
Either you have to allow headers Access-Control-Allow-Origin:* in both frontend and backend or alternatively use this extension cors header toggle - chrome extension unless you host backend and frontend on the same domain.
Try running this command in your terminal and then test it again.
curl -H "origin: originHost" -v "RequestedResource"
Eg:
If my originHost equals https://localhost:8081/ and my RequestedResource equals https://example.com/
My command would be as below:
curl -H "origin: https://localhost:8081/" -v "https://example.com/"
If you can notice the following line then it should work for you.
< access-control-allow-origin: *
Hope this helps.
Do specify #CrossOrigin(origins = "http://localhost:8081")
in Controller class.
You can solve this temporarily by using the Firefox add-on, CORS Everywhere. Just open Firefox, press Ctrl+Shift+A , search the add-on and add it!
You won't believe this,
Make sure to add "." at the end of the "url"
I got a similar error with this code:
fetch(https://itunes.apple.com/search?term=jack+johnson)
.then( response => {
return response.json();
})
.then(data => {
console.log(data.results);
}).catch(error => console.log('Request failed:', error))
The error I got:
Access to fetch at 'https://itunes.apple.com/search?term=jack+johnson'
from origin 'http://127.0.0.1:5500' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
But I realized after a lot of research that the problem was that I did not copy the
right URL address from the iTunes API documentation.
It should have been
https://itunes.apple.com/search?term=jack+johnson.
not
https://itunes.apple.com/search?term=jack+johnson
Notice the dot at the end
There is a huge explanation about why the dot is important quoting issues about DNS and character encoding but the truth is you probably do not care. Try adding the dot it might work for you too.
When I added the "." everything worked like a charm.
I hope it works for you too.
install:
npm i cors
Then include cors():
app.get("/list",cors(),(req,res) =>{
});
In addition to the Berke Kaan Cetinkaya's answer.
If you have control over your server, you can do the following in ExpressJs:
app.use(function(req, res, next) {
// update to match the domain you will make the request from
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
https://enable-cors.org/server_expressjs.html
I tried this code,and that works for me.You can see the documentation in this link
var io = require("socket.io")(http, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
})
The reason that I came across this error was that I hadn't updated the path for different environments.
you have to customize security for your browser or allow permission through customizing security. (it is impractical for your local testing)
to know more about please go through the link.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
These errors may be caused due to follow reasons, ensure the following steps are followed. To connect the local host with the local virtual machine(host). Here, I'am connecting http://localhost:3001/ to the http://abc.test Steps to be followed:
1.We have to allow CORS, placing Access-Control-Allow-Origin: in header of request
may not work. Install a google extension which enables a CORS request.*
2.Make sure the credentials you provide in the request are valid.
3.Make sure the vagrant has been provisioned. Try vagrant up --provision this make the localhost connect to db of the homestead.
Try changing the content type of the header. header:{ 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8;application/json' }
this point is very important.
Another solution to this problem in a specific scenario :
If
AWS APIGW is your backend with authentication enabled and
authentication fails,
your browser may end up complaining about CORS even if CORS is enabled in APIGW. You also need to enable CORS for 4XX as follows
API:YourAPI > Resources > /YourResource > Actions > Enable CORS > Gateway Responses for yourAPI check Default 4XX
Authentication will still fail but it won't look like CORS is the root cause
$.get('https://172.16.1.157:8002/firstcolumn/' + c1v + '/' + c1b, function (data) {
// some code...
});
Just put "https" .

'Access-Control-Allow-Origin' error in request js

I'm writing an angular 2 app which uses a module called github-trend. I have a service which calls some functions from the module
scraper.scrapeTrendingRepos("").then(function(repos) {
repos.forEach(function(repo) {
//more code here
});
}).catch(function(err) {
console.log(err.message);
});
For now I'm testing my angular app with Chrome(56.0.2924.87) on http://localhost:3000/ and its giving me an Access-Control-Allow-Origin, here is full message:
Fetch API cannot load https://github.com/trending. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
data.service.ts:43 Failed to fetch
I've searched around and know that this might be happening because get request and server are working on differnt ports? Looking at the repo, the github-trend module using requestjs to make http requests but I'm not sure how to fix this. Is there a way I can make it work on chrome? What should I modify in the module code so as to make it work?
Solved the problem by using an Allow-Control-Allow-Origin extension for chrome.

Where's the CORS setting gone in azure mobile services

TL/DR:
MSDN azure articles refer to going to the "Configure" section of the https://manage.windowsazure.com/ mobile services settings to add other URLS to CORS. It seems it isn't there anymore - any idea where it's gone?
The longer story for background:
Trying to follow this article:
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/
and this linked one:
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-get-started-data/
I have followed the article and created an azure mobile service with a sql server database (and 1 simple table in it.)
I then try to connect to it on my web server (localhost:8000/) with the js code:
var MobileServiceClient = WindowsAzure.MobileServiceClient;
var client = new MobileServiceClient('https://myappnamehere.azure-mobile.net/', 'mykeyhere');
I then make a call to query some data:
var table = client.getTable('mytablename');
var query = table.where({
complete: false
}).read().done(function (results) {
console.log(results);
}, function (err) {
console.log(err);
});
And the where call runs the error callback with the message:
"XMLHttpRequest cannot load
https://myappnamehere.azure-mobile.net/tables/tablename?$filter=(complete%20eq%20false).
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'localhost:8000' is therefore not allowed
access."
I'm guessing this is because although localhost is meant to be allowed in the server side CORS settings localhost:8000 isn't.
Trouble is, both articles above refer to going to the "Configure" section of the https://manage.windowsazure.com/ mobile services settings to add other URLS to CORS. It seems it isn't there anymore - any idea where it's gone?
All the other articles I look for talk about setting it in your config file etc. but the point is I don't want to push code to the server-side. That 1st article definitely implies that I can just create the service and the sql server table and then talk to it from javascript client-side (presumably automagically through the use of OData.) That is possible right or is that part of the article completely wrong too?!
If you're using the JavaScript (node.js) backend, then you'll see the list of cross-origin resource sharing (cors) domains. On the .NET backend, the support isn't baked in yet, but you should be able to add it by following the instructions to enable CORS for Web API (after all, the .NET backend is built on top of that platform).
Since you're accessing your service at localhost, I'm assuming that you're using the .NET backend, which is why you won't see the list of CORS domains in the portal. The integrated support should be coming in soon, but before that you can add the support manually as described in the document linked above.

Serving static files in connectjs with 'Access-Control-Allow-Origin' set to '*'

I'm using Connect.js to serve my static files in a Node.js application; however, I want to be able to make GET requests to those static files from multiple origins, so I'd like to be able to set 'Access-Control-Allow-Origin' : '*' in the response header for these static files.
My question is, how would I go about doing this with Connect? Here's my server so far:
var connect = require('connect');
var server = connect(
connect.static(__dirname + '/public')
);
server.listen(8080);
Access-Control-Allow-Origin only applies to ajax requests, generally speaking. When you're serving static files, you don't need to worry about that particular header. Anyone can request those files, regardless of origin, in the default configuration.
You run into issues when you serve a regular page, and then you want to request via javascript FROM that page. Then you need to set your Access-Control-Allow-Origin policy to allow ajax requests to other domains from that particular page.
Further, you most often run into this when attempting to access a web service. Its very common to use JSONP in those cases, instead of using that particular header. Especially not * since it introduces security risks. See http://www.ibm.com/developerworks/library/wa-aj-jsonp1/ and http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
MDN resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Josh

Categories

Resources