'apollo-client does not work with CORS
I am writing a graphql server component on AWS Lambda (NOT using graphql-server). On the client side I'm using apollo-client. On the response of the lambda function I'm setting
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*" // Required for CORS support to work
},
body: JSON.stringify({
result: 'mock data',
input: event,
}),
};
callback(null, response);
On the client side using ApolloClient I get the following error
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
However when I execute the same request using something like axios then it works fine. Furthermore when I just execute the request over something like postman I see the "Access-Control-Allow-Origin" setting enabled on the response. Is this a known issue with apollo-client and how do I fix this?
Solution 1:[1]
To workaround the CORS issue with Apollo you have to pass the no-cors option to the underlying fetch.
import ApolloClient from "apollo-boost";
const client = new ApolloClient({
uri: "your client uri goes here",
fetchOptions: {
mode: 'no-cors',
},
});
This is not a specific Apollo problem, rather a configuration that is meant to be tackled on the fetch side, see this for more information: https://developers.google.com/web/ilt/pwa/working-with-the-fetch-api#cross-origin_requests
I wonder why it does works with Axios for you, I'd expect you to have the no-cors mode set somewhere.
Solution 2:[2]
I'd assume you're using the AWS API Gateway.
One question for you is: have you enabled CORS for your gateway? See how
I believe that should solve your issues, if you're also sending cookies, you can also set the "Access-Control-Allow-Credentials" : true header as well.
`
Solution 3:[3]
the first, fault we are doing is importing ApolloClient from 'apollo-boost'. Actually we have to import ApolloClient from 'apollo-client'.
import ApolloClient from 'apollo-client';
Because, ApolloClient from apollo-boost only supports a smaller subset of configuration options. ApolloClient from apollo-client gives you all the configuration options.
then we can provide link and cache only to Apollo-client instance
import { InMemoryCache } from "apollo-cache-inmemory";
import { createHttpLink } from 'apollo-link-http';
const client = new ApolloClient({
link: new createHttpLink(
{
uri: "Your QraphQL Link"
}
),
cache: new InMemoryCache(),
});
Solution 4:[4]
The accepted answer is correct for Apollo client 2.x.x.
For Apollo client >= 3.0.0 you can use:
import { ApolloClient, HttpLink } from '@apollo/client';
const client = new ApolloClient({
link: new HttpLink({
uri: 'your client uri goes here',
fetchOptions: {
mode: 'no-cors'
}
}),
});
Solution 5:[5]
here is a working example. the server must have CORS enabled. that means the origin of your http request
origin: https://example.com
must match the access-control-allow-origin header of the response to your request.
access-control-allow-origin: https://example.com
Then on the Angular client you can use this module:
import {NgModule} from '@angular/core';
import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular';
import {HttpLinkModule, HttpLink} from 'apollo-angular-link-http';
import {InMemoryCache} from 'apollo-cache-inmemory';
import {environment} from 'src/environments/environment';
import {errorLink} from './dm-core/graphql/apollo-link-error';
import {concat} from 'apollo-link';
export function createApollo(httpLink: HttpLink) {
return {
link: concat(errorLink, httpLink.create({uri: environment.graphql, withCredentials: true})),
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
errorPolicy: 'all'
}
}
};
}
@NgModule({
exports: [ApolloModule, HttpLinkModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink]
}
]
})
export class GraphQLModule {}
Note the "withCredentials: true":
link: concat(errorLink, httpLink.create({uri: environment.graphql, withCredentials: true})),
Solution 6:[6]
You are pretty close to the attended result, keep in mind that waitForSelector uses a query selector to return an HtmlElement object. You need to use this object for the click method:
await page.click('#continue');
const homedeliv = await page.waitForSelector('#delivery-home-delivery');
if (homedeliv) {
console.log("we found home delivery item in checkout page");
}
await homedeliv.click(); // Here you use homedeliv variable
Try to keep this logic for all your scrap code, I also suggest you to put some delay in your script, such as navigation delays or click delays to act like a human. Some website have anti-bots system that can ban your ip if it detects strange behaviour from your side.
And for your rect method, you should be able to use a query selector in order to double click the desired radio button, you generally don't want to move yourself your cursor.
You can always verify this with your browser inspector, some hints:
- Try to freeze your page so you can catch the html element you want
- Try to always use query selector or xpath
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ivanalejandro0 |
| Solution 2 | oreoluwa |
| Solution 3 | |
| Solution 4 | Mahdi Aryayi |
| Solution 5 | David Dehghan |
| Solution 6 | Lucas Gras |
