CORS policy issue while reading RSS Feed in React - javascript

I am trying to create a react App where I need to parse some RSS news feeds from url "https://news.google.com/news/rss" but I am getting an error "request has been blocked by CORS policy: "No 'Access-Control-Allow-Origin' header is present on the requested resource". I did the similar project in Android app where I fetched some feeds using AsyncTasks in java it didn't showed me any CORS issue, I want to understand why it worked on Android app and not in Web Application? Is it the browser that is enforcing the CORS or is the google server that is enforcing some sort of CORs policy?
let xmlText;
axios
.get(
"https://news.google.com/news/rss",
)
.then((response) => {
xmlText = response;
return response;
})
.then((textResponse) => {
console.log("Fetching response as", textResponse);
xmlText = textResponse;
})
.catch((error) => {
console.log(error);
});

You can use a plugin
google-news-json
Google News JSON API
Installation
npm install --save google-news-json
Or
yarn add google-news-json
Usage
Usage example:
let googleNewsAPI = require("google-news-json");
let news = await googleNewsAPI.getNews(googleNewsAPI.TOP_NEWS, null, "en-GB");
Also supports callback
googleNewsAPI.getNews(googleNewsAPI.SEACRH, "apple", "en-GB", (err,response) => {
console.log(response);
});
Parameters
Method (defaults to TOP_NEWS or HIGHLIGHTS)
Query (this is ignored when method is TOP_NEWS or HIGHLIGHTS)
Locale (defaults to en-GB)
Callback (not required)
Methods
HIGHLIGHTS, TOP_NEWS, LOCATION, SEARCH, TOPIC, GEO
Supported TOPICS
TOPICS_WORLD, TOPICS_NATION, TOPICS_BUSINESS, TOPICS_TECHNOLOGY, TOPICS_ENTERTAINMENT, TOPICS_SCIENCE, TOPICS_SPORTS, TOPICS_HEALTH

Related

Google Places API returns Error: Network Error when using Axios

When use python requests and send the following
outs = requests.get("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=32.78257453407587,-117.11499507124117&radius=15000&keyword=Paddle+Board+Rentals&key=MY_KEY")
I get a status 200 and results.
When I issue with Axios
async getPlaces(point, radius, keywords, type=""){
const url = this.urlBuilder(point, radius, keywords, type);
const response = await axios.get(url)
.then(res => {return res})
.catch(err => {return err});
return response
}
And the url is the exact same in the python above, I get
Error: Network Error
Is there a default header in python that could be causing the difference between the two requests?
Edit:
Using console.log I was able to get this error
Error: Cross origin http://localhost forbidden
So there's an issue from running google places request with fetch or axios because they are coming from local host.
The issue was that google will not allow users to make these network calls over https with javascript. You must use the google places api.

request method showing 403 error in node js

app.post("/",function(req,res){
// console.log(req.body.crypto);
request("https://apiv2.bitcoinaverage.com/indices/global/ticker/all?crypto=BTC&fiat=USD,EUR",function(error,response,body){
console.error('error:', error);
console.log(response.statusCode);
});
From the documentation:
All requests to our API must be authenticated with your public key.
First register an account.
Then choose one of our plans from the plans page.
Finally get your public key from the main dashboard.
You're not passing any key in your request.
You are seeing that error with 403 (Forbidden) status code because the API you are trying to use requires an API key. You can see it in their API documentation.
What you should do is following the steps mentioned in API documentation and get a API key. Then you should to use this API key as x-ba-key header for your future requests like below:
I suggest you to use axious package to make your API calls since request module is deprecated and they will not support future issues and versions. Install axios package using npm install axios command and then import it to your application file. Then make a request to the endpoint with your API key like this:
const options = {
headers: { 'x-ba-key': 'yourAPIKey' }
};
axios.get('https://apiv2.bitcoinaverage.com/indices/global/ticker/all?crypto=BTC&fiat=USD,EUR', options)
.then((response) => {
console.log(response);
}, (error) => {
console.log(error);
});

Api is not fetching in reactJs

I am trying to fetch food by its key. In postman api is working fine but is the forntend it has no response.
backend code
app.get('/foods/:key', (req, res) => {
foodsCollection.find({ key: req.params.key }).toArray((err, documents) => {
res.send(documents[0])
})
})
frontend code
const { key } = useParams()
const [foodById, setFoodById] = useState({})
useEffect(() => {
fetch(`http://localhost:5000/foods/${key}`)
.then((res) => res.json())
.then((data) => {
setFoodById(data)
})
}, [key])
Although you've added some images above, the most important is missing, namely, what are the Browser's Developer Tools stating the problem is. You should see some message in the Console tab, as well as in the Network tab for that particular request, if it is indeed being made. Until anyone sees this, it will be very difficult to help in fixing your problem.
If your not already, I suggest scaffolding any react app with create-react-app (CRA). This will give you a working app to start from. You can ignore CORS related issues in development, if using CRA, by adding "proxy": "http://localhost:5000", to your package.json file, see here for more on this method, but remember, this is only works for local development. You can also start Chrome to ignore Web Security by running it with the --disable-web-security flag e.g. chromium --disable-web-security, but that isn't a great idea really, more a way to quickly determine if you are having CORS problems, as Chrome masks some problems as CORS related, when in fact they aren't.
I'd also suggest changing your fetch code to use await, so instead you'd have:
const response = await fetch(`http://localhost:5000/foods/${key}`);
if (!response.ok) {
console.error(`Error message: ${response.statusText} ${response.status}`);
}
const result = response.json();
console.log(result);
This isn't necessary, but I've always found it way easier to read than the then/catch/finally method.
Reason for error
You need to stringify an object before sending it to the client with the JSON.stringify() method. When we exchange data to/from a web server, it must be a string.
Solution:
Proper way to send response to the client would to wrap the entire API in a try-catch block and explicitly specify the HTTP Status Code along with the stringified data in every response.
Note: Although 500 status code is used for error handling, you should choose one as per the use case.
app.get('/foods/:key', (req, res) => {
try {
/*
rest of the code
*/
foodsCollection.find({ key: req.params.key }).toArray((err, documents) => {
if (err) {
// 500 stands for internal server error
return res.status(500).send(JSON.stringify('Here goes a meaningful error message!'));
}
// 200 stands for success
res.status(200).send(JSON.stringify(documents[0]));
});
/*
rest of the code
*/
} catch (error) {
// 500 stands for internal server error
res.status(500).send(JSON.stringify('Here goes another meaningful error message!'));
}
})
The problem is that you haven't set the CORS headers of response in your backend code. and you are using different ports in your backend and frontend (5000 & 3000) so the Same Origin Policy disallows reading the remote resource, indicating that the request was blocked due to violating the CORS security rules.
you've to set the CORS headers.
you can install the CORS npm package and follow it's instructions to resolve the issue like this:
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
.
.
.
And one other issue that I'm seeing is that you've put the react-router default route before your specified path. so move the <route path="*"> after <route path="/foods/:key">

Azure Chatbot Token Server

I have an azure chat bot and I use it per direct line channel.
It is working fine if I use the secret directly in the HTML, but due to safety reasons I want to use Tokens. Thats why I used that:
<script>
window
.fetch('http://XXXXXXXX.azurewebsites.net/token-generate',
{
method: 'POST'
})
.then(function(res) {
return res.json();
})
.then(function(json) {
const token = json.token;
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({
token: token
})
},
document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
});
</script>
It is like that and not with an async function because it needs to work on IE11 too.
My index.js in my bot looks like this:
// Create HTTP server
const server = restify.createServer({
name: 'token-server'
});
server.listen(process.env.port || process.env.PORT || 3978, function() {
console.log(`\n${ server.name } listening to ${ server.url }`);
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});
server.post('/token-generate', async (_, res) => {
console.log('requesting token ');
res.setHeader('Access-Control-Allow-Origin', '*');
console.log(res);
try {
const cres = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', {
headers: {
authorization: `Bearer ${ process.env.DIRECT_LINE_SECRET }`
},
method: 'POST'
});
// console.log(cres);
const json = await cres.json();
// console.log(json);
// json.header.append('Access-Control-Allow-Origin: *');
console.log(json);
if ('error' in json) {
res.send(500);
} else {
res.send(json);
}
} catch (err) {
res.send(500);
}
});
That is some code I found after some research how to use tokens to render the Webchat.
My problem is, that when I use this html code, I get some Errors:
Access to fetch at 'http://compliancebotbbraun-bot.azurewebsites.net/token-generate' 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.
testbot.html:1 Uncaught (in promise) TypeError: Failed to fetch
and I just don't know how to change the Access-Control-Allow-Origin header. I don't find anything online and if I find something, it is not even close to my code.
It is working exactly as I tought it would work in IE11, but in Chrome,Edge and Firefox (idk for others, only tested these) these Errors are occuring.
I hope someone here can help me.
Based on my understanding , you exposed an API to grant access tokens to your bot clients by post method to your bot clients. Your bot clients use JS script to invoke this API . As you are using post method, so your bot clients will encounter CORS issues .
Based on the host of /token-generate url , this API is hosted on Azure webapp , you can just refer to this doc to define allowed domains to call this API from a static page by JS on Azure portal directly.
You can find the Azure webapp which hostes your API code here :
And open CORS settings here :
If you are just testing your bot from local static html file , adding "*" and remove other domains in CORS config will solve this issue .
Test result :
Hope it helps . If you have any further concerns , pls feel free to let me know .

Can't fetch data, CORS issue, trying to hack it with JSONP, still not working

I'm trying to fetch data from http://www.recipepuppy.com/api/?q=onion&p=1. (Sample query)
It works in a browser, but I was trying to fetch it inside my React app and I'm encountering “No 'Access-Control-Allow-Origin' header is present on the requested resource error.
So I changed my strategy and now I'm trying to use JSONP (https://github.com/mzabriskie/axios/blob/master/COOKBOOK.md#jsonp).
But I can't make it work. I'm getting this error all the time. Can someone please help me with my issue?
Error:
Uncaught ReferenceError: jp0 is not defined
at ?q=onion&p=1&callback=__jp0:1
My Code:
import jsonp from 'jsonp'
export const FETCH_RECIPES = 'FETCH_RECIPE'
export const SHOW_INFO = 'SHOW_INFO'
export function fetchRecipes (searchTermToDOoooooooooo) {
const request = jsonp('http://www.recipepuppy.com/api/?q=onion&p=1', null, function (err, data) {
if (err) {
console.error(err.message)
} else {
console.log(data)
}
})
return (dispatch) => {
/*
request.then(({ data: data1 }) => {
dispatch({ type: FETCH_RECIPES, payload: data1 })
})
*/
}
}
export function showInfo (info) {
return {
type: SHOW_INFO,
payload: info
}
}
How that error looks in dev tools:
You can't do it with client-only code, at least not with JSONP+Axios (Axios doesn't (natively) support JSONP; the "jsonp" library is different from Axios), because it's the server you're getting information from that's in violation of the cross-origin rules. In this case, it's Recipe Puppy that isn't set up for Access-Control-Allow-Origin headers.
One option is to use a server-side proxy, as #Pointy mentions.
Your flow would then shift to:
Client calls server-side proxy for information.
Proxy calls Recipe Puppy's API and translates or passes through information as needed.
Proxy relays that information to the client-side code for further processing.
As for your current shift to jsonp, it appears the jsonp library is not exporting jp0 properly for some reason. This could be an error with your build tool. You'll want to double-check your setup and make sure your build tool is picking up the jsonp library and actually putting it into the compiled source.

Categories