How to add custom HTTP headers in React application? - reactjs

I have a react js application. I want to add some http headers in the every response that's being returned from the app. Could you please suggest how to implement this !
NOTE : I am not trying to call any api with headers in request. I want my react app to respond with some custom headers in the response

As Dovlet Mamenov mentioned in the comment, this has to be done on the web server wherever react app is hosted.
For example, If react app is hosted on the Apache server, then these http headers in the response should be added on the Apache server conf.

const header = new Headers();
header.append('Access-Control-Allow-Origin', '*');
const body = {
author: author,
text: text
}
axios.post("https://api.test/posts/create", body, header)
.then((res) => {
this.setState({
result: res
});
})
.catch((error) => {
this.setState({
error: error.message
});
})
You have to use the native object Headers, and add it in axios.

Related

Cors Issues in React project using Vercel

I have a react project, and yesterday I deployed it in vercel, now I have a CORS issue. Could you tell me how can I solve it?
Thanks in advance.
I want to deploy a react project using an API from Zoho Catalog. here my request.
useEffect(()=>{
const peticion = fetch(urlPost,{
method: 'POST',
});
peticion
.then((ans)=>{return ans.json()})
.then((resp)=>{
const reslt = resp.access_token;
return fetch(urlGet,{
method: "GET",
headers:{
'Authorization':`Zoho-oauthtoken ${reslt}`,
}}
)})
.then((answer) => { return answer.json() })
.then((resp) => {
const result = resp.data
setData(result)
setFiltered(result)
})
},[])
There are 2 ways of dealing with it. The first method would be allowing cors in your server, if you have a nodejs server then you can add the following code into your server.js file
const cors = require("cors")
app.use(cors())
if you don't have a nodejs server then you can google how to enable cors in the respective language your server is using. This only works if you have access to the server, if you don't have access to your server you can try the second method.
The second method would be using a proxy server. You can follow this video on how to do it or you can read this post

How to fetch data from a REST API by using an API-Token

I'm trying to fetch data from the Jira Rest API in my React application by using the Axios library for http requests. An API token is necessary, in order to access data via the Jira API. I generated an API token in my Jira account settings, but I can't figure out, how to include it in my http request to gain access.
This is the endpoint provided by the Jira documentation for getting an issue from the Jira board:
curl -u admin:admin http://localhost:8080/jira/rest/api/2/issue/TEST-10 | python -mjson.tool
This is the React state hook for setting the data to the fetched data:
const [jiraTicket, setJiraTicket] = useState([]);
This is the fetch function for the API request (${} will be filled with user input):
function getJiraTicket() {
axios.get(`${username}:${apiToken}#Content-Type:application/json/https:/${jiraSiteName}.atlassian.net/rest/api/2/issue/${projectKey}-${ticketId}`)
.then((res) => {
const data = res.data;
setJiraTicket(data);
})
}
The button inside the react component return should invoke the fetch function:
return(
<Container>
<Button onClick{getJiraTicket()}>Fetch Jira Ticket</Button>
</Container>
);
This is the error I'm currently getting, because the authorization is not working the way I did it
(I replaced the provided username, API token etc. for this example):
GET http://localhost:3000/username:apitoken#https:/sitename.atlassian.net/rest/api/2/issue/projectkey-ticketid 404 (not found)
Edit:
My current approach:
function getJiraTicket() {
axios.get(`${userName}:${apiToken}#https://${siteName}.atlassian.net/rest/api/2/issue/${projectId}-${ticketId}`,{
auth: {
username: userName,
password: apiToken,
},
withCredentials: true
})
.then((res) => {
const data = res.data;
console.log(data);
setJiraTicket(data);
})
.catch(err => {
// This error means: The request was made and the server responded with a status code
if(err.res) {
console.log(err.res.data);
console.log(err.res.status);
console.log(err.res.headers);
console.log("request was made and server responded with status");
// The request was made but no response was received
} else if (err.request) {
console.log(err.request);
console.log("request was made, but no response was received");
// Something happened in setting up the request that triggered an error
} else {
console.log("Error", err.message);
console.log("request is note set up correctly");
}
console.log(err.config);
})
Current error, which I defined accordingly to the axios doc: "request was made, but no response was received"
Endpoint that works well in Postman (Basic auth is provided in Postman):
https://sitename.atlassian.net/rest/api/2/issue/projectid-ticketid
Update: CORS access isn't allowed, when an application tries to access the Jira API endpoints directly. This restriction takes place in order to prevent random authenticated requests to the specific Jira site, because the access is based on session based authentication. However the API endpoints can be accessed, if OAuth 2.0 is used instead of Basic auth, because the application will redirect the user to the Jira auth itself via this link:
https://auth.atlassian.com/authorize? audience=api.atlassian.com&
client_id=YOUR_CLIENT_ID&
scope=REQUESTED_SCOPE_ONE%20REQUESTED_SCOPE_TWO&
redirect_uri=https://YOUR_APP_CALLBACK_URL&
state=YOUR_USER_BOUND_VALUE& response_type=code& prompt=consent
Source: https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/#known-issues
Axios uses a headers config for get/post so you should not include them in your URL. Here is a general example of how you should construct the URL and apply headers:
let axiosUrl = `https://${jiraSiteName}.atlassian.net/rest/api/2/issue/${projectKey}-${ticketId}`
axios({
baseURL: axiosUrl,
method: 'get',
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin", "*"
},
//timeout: 2000,
auth: {
username: userName,
password: apiToken,
}
})
.then((res) => {
setJiraTicket(res.data);
})
.catch(function (error) {
console.log(error);
});

NextJs CORS issue

I have a Next.js app hosted on Vercel at www.example.com, which needs to communicate with a backend .NET Core Web API hosted on a different server at api.example.com.
The .NET core web api has been configured to allow CORS but my Next.js keeps complaining that data cannot be displayed when I use AXIOS to fetch data because the response lacks allow-cors headers:
Access to XMLHttpRequest at 'https://api.example.com' from origin 'http://www.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
It works fine when I run it locally using npm run dev, but doesn't work when I build it and then run npm run start
Does anyone know how to fix the cors issue in production?
I found a solution here:
Basically, I just need to add a next.config.js file in the root directory and add the following:
// next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://api.example.com/:path*',
},
]
},
};
if you want to use the cors library in nextjs, I created a library for it is nextjs-cors.
https://www.npmjs.com/nextjs-cors
https://github.com/yonycalsin/nextjs-cors
pages/api/whoami.{ts,js}
import NextCors from 'nextjs-cors';
async function handler(req, res) {
// Run the cors middleware
// nextjs-cors uses the cors package, so we invite you to check the documentation https://github.com/expressjs/cors
await NextCors(req, res, {
// Options
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
origin: '*',
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
});
// Rest of the API logic
res.json({ message: 'Hello NextJs Cors!' });
}
it was a problem in the server not accepting OPTIONS requests, because routes were declared as GET::something or POST:: something, so the preflight couldn't pass and the POST request was decliend, hope this will help another people to prevent hours of googling, so in my case (Node.js + Express.js) i had to add this to my server.js
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
if (req.method == "OPTIONS") {
res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET");
return res.status(200).json({});
}
next();
});
I had a similar issue, I was making the call from this page:
pages/page1.js
export default async function page1() {
const data = await axios.post('https://www.dominio.com/xxx' , {param: 1}, headers)
}
But the solution is to make axios calls to a local API file inside "pages/api" directory, and this local API file, will handle the request to the external webserver. This avoid the CORS issue.
pages/page1.js
export default async function page1() {
const data = await axios.post('/api/get_page1_data', {param: 1} )
}
pages/api/get_page1_data.js
export default async function handler(req, res) {
try{
const data = await axios.post('https://www.dominio.com/xxx' , {param: req.body.param}, headers)
res.status(200).json(data)
} catch (error) {
console.error(error)
return res.status(error.status || 500).end(error.message)
}
Do an extra check if your base URL is correct that was my issue
In my case, the preflight request was failing due to an agressive HTTP method filter.
Make sure that you specify
// Preflight Check:
if (req.method == "OPTIONS") {
res.setHeader("Allow", "POST");
return res.status(202).json({});
}
// Allow only POST Methods
if (req.method !== "POST") {
res.setHeader("Allow", "POST");
return res.status(405).json({ error: `Method ${req.method} Not Allowed` });
}
You can allow all methods with https://vercel.com/support/articles/how-to-enable-cors#enabling-cors-in-a-next.js-app, but make sure that each endpoint returns a 2XX status code for the OPTIONS HTTP method.
Please make sure it is CORS and is not something else. For example, in my case I was getting a 400 response. Please look on the Response tab of that request for information.
after hours of googleing i found the solution on the next-docs itself!!!
see the following repository on github
API Routes Example with CORS
https://github.com/vercel/next.js/tree/canary/examples/api-routes-cors
I had this issue taking a SoloLearn NestJS course and it was resolved by adding the line: app.enableCors() in main.ts file on the root folder in the NESTJs Project.
The file was like this:
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
}
bootstrap();
I have Next.js application that has graphql and Apollo Client setup (apollo version : 3.5.10). In order to make a query inside any component you have to use "client" variable that Apollo Client provide. You need to have apollo-client.js file in your project root so that Apollo Client can use it inside any component for query. Inside any component when you trying to make a query like: client.query(...), with these settings of apollo-client file it will throw "cors" error. However you can fix this by adding headers property inside apollo-client file.
This is OLD Settings:
apollo-client.js (old)
import { ApolloClient, InMemoryCache } from '#apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
cache: new InMemoryCache(),
});
export default client;
This is NEW Settings:
apollo-client.js (new)
import { ApolloClient, InMemoryCache } from '#apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
cache: new InMemoryCache(),
headers: {
fetchOptions: {
mode: 'no-cors',
},
},
});
export default client;
By doing this, you won't get any "cors" error while doing query inside any component.

why does react.js when upload file return cors

const formData = new FormData();
formData.append("CustomerName", this.state.customerName);
formData.append("Email", this.state.email);
formData.append("Phone", this.state.phone);
formData.append("PageNumber", this.state.pagesNumber);
formData.append("Notes", this.state.notes);
formData.append("WritingConversionTypeId", this.state.writingConversionTypeId);
formData.append("WritingDocumentTypeId", this.state.writingDocumentTypeId);
formData.append("WritingTimePeriodId", this.state.writingTimePeriodId);
formData.append("files", 'null');
writingRequest.postwritingRequest(formData).then((res) => {
console.log(res);
});
when attach to headrs form data it return CORS
i'm using react.js and server side ASP.NET Core3.1...
and it works when removing the (Content-Type: multipart/form-data) from headers
it works in swagger
enter image description here
in
at React Service to Call Api
import http from "../../config/http";
import endPoints from "../endPoints";
const writingRequestUrl = endPoints.WRITING_REQUEST_ENDPOINT;
export default {
postwritingRequest(writingRequest) {
return http
.post(
writingRequestUrl,
writingRequest
, {
headers: {
'enctype': 'multipart/form-data',
"Content-Type": "multipart/form-data"
},
}
)
.then((res) => {
return res;
});
},
};
In StartUp
At ASP.NET CORE
ConfigureServices
//Enable CROS To allow access to the resource
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
}));
In Configure
app.UseCors("MyPolicy");
CORS has nothing to do with react, your browser prevents the call as the client runs on a different domain than your server. On production this is usually not an issue, since both are typically running on the same domain.
If you want to avoid CORS in development, the Create React App bundle comes with a proxy server, that appends the CORS header to all HTTP requests, as described in the documentation.
Simply add the URL to your api to your package.json like so:
"proxy": "www.url-to-your-api.com"
Then make sure to run all requests from your react app against absolute links, so instead of calling www.url-to-your-api.com/api/ you should simply use /api/, this will use the proxy in development and the regular route in production.

Axios Interceptors with given token, React

After this request:
axios
.post(url_auth, obj)
.then(response => {
const info = response.data
this.setState({info})
})
.catch(error => {
console.log(error);
});
I store inside info a JSON with id and token. (backend sent it to me)
I would like now to store token in the headers of every request I made.
How do I make it with? I guess with interceptor? Once I configure the headers inside the interceptor (I'm trying to understand how), how do I call it in my request?
Thank you very much!
Yes this can be done with the interceptors.Refer this article
Also you can refer one of my repo,The project is in Angular & Node.Used Token for validating the request

Resources