Comments (28)
This is probably the one we want to to support:
https://github.com/matthew-andrews/isomorphic-fetch
from react_on_rails.
I'd be happy to have this as part of react_on_rails. It's really a very common requirement.
from react_on_rails.
@anpr I think part of the standard npm package for react-on-rails is fine if it's very small.
from react_on_rails.
My two cents. I use this:
import _ from 'underscore'
/* globals document */
export default class BaseData {
constructor() {
this.defaultParams = {
credentials: 'same-origin'
}
}
getCSRFToken() {
return _.find(document.getElementsByTagName("meta"), (meta) => {
return meta.name === "csrf-token"
}).content
}
defaultHeaders = () => {
return {
'X-CSRF-Token': this.getCSRFToken(),
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json'
}
}
post = (url, props) => {
return fetch(url, {
method: 'post',
headers: this.defaultHeaders(),
body: JSON.stringify(props),
...this.defaultParams
})
.then((response) => {
return response.json()
})
}
put = (url, props) => {
return fetch(url, {
method: 'put',
headers: this.defaultHeaders(),
body: JSON.stringify(props),
...this.defaultParams
})
.then((response) => {
return response.json()
})
}
delete = (url) => {
return fetch(url, {
method: 'delete',
headers: this.defaultHeaders(),
...this.defaultParams
})
.then((response) => {
return response.json()
})
}
}
And this module: "whatwg-fetch": "^0.9.0"
And in the webpack config:
new webpack.ProvidePlugin({
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
})
from react_on_rails.
We're using axios here:
https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/package.json
@alexfedoseev Are we missing the headers for:
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json'
Here's our source: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client%2Fapp%2Futils%2FcommentsManager.js
import request from 'axios';
const API_URL = 'comments.json';
const CommentsManager = {
/**
* Retrieve comments from server using AJAX call.
*
* @returns {Promise} - result of ajax call.
*/
fetchComments() {
return request({
method: 'GET',
url: API_URL,
responseType: 'json',
});
},
/**
* Submit new comment to server using AJAX call.
*
* @param {Object} comment - Comment body to post.
* @returns {Promise} - result of ajax call.
*/
submitComment(comment) {
return request({
method: 'POST',
url: API_URL,
responseType: 'json',
headers: {
'X-CSRF-Token': this.getCSRFToken(),
},
data: { comment },
});
},
/**
* Get CSRF Token from the DOM.
*
* @returns {String} - CSRF Token.
*/
getCSRFToken() {
const metas = document.getElementsByTagName('meta');
for (let i = 0; i < metas.length; i++) {
const meta = metas[i];
if (meta.getAttribute('name') === 'csrf-token') {
return meta.getAttribute('content');
}
}
return null;
},
};
export default CommentsManager;
from react_on_rails.
Are we missing the headers for
No, since we don't use Vendor MIME Type to match the api version (we use URL instead).
More on subject: https://medium.com/@alexfedoseev/isomorphic-react-with-rails-part-ii-614980b65aef
And example of apiCall
helper with axios
:
import http from 'axios';
import getCSRFToken from './getCSRFToken';
const apiURLPrefix = '/api/v1';
// Transforming Immutable data to plain JS
http.defaults.transformRequest.unshift(data => (
data && data.toJS === 'function' ? data.toJS() : data
));
http.interceptors.request.use(config => {
// If it's not remote call, adding api prefix
if (!config.remote) {
config.url = `${apiURLPrefix}${config.url}`;
}
// Adding CSRF Token header
config.headers = {
'X-CSRF-Token': getCSRFToken(),
};
return config;
});
export default params => http(params);
from react_on_rails.
👍 I'm using that because I'm using a jsonapi-resources backend, which requires that MIME type
from react_on_rails.
@alexfedoseev @josiasds @mapreal19 How about we release a tiny npm module to encapsulation axios and the ability to get the CRSF token from Rails? Then we can put the inclusion of the tiny npm module in the template setup.
from react_on_rails.
I'd rather made getCRSFToken
module and left axios
in user land.
Reasons:
axios
is opinionated.axios
's setup is opinionated.
from react_on_rails.
@jbhatab @alexfedoseev Once we put in the NPM library, I'll try to merge in the code from the: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/metaTagsManager.js
from react_on_rails.
@justin808 @alexfedoseev @jbhatab
Regardless though, I vote we do not put this in the npm module for the same reason that Alex chose not to use Axios's implementation. Some people may not even be doing sessions this way.
from react_on_rails.
Just to leave another implementation here for the sake of brainstorm. We only use helper methods that don't wrap fetch, but aid in parameter setting. Implementation in this gist.
For regular non-safe json requests:
fetch('/foobar.json', jsonHeader(/*fetch options*/));
With just the Rails CSRF headers:
fetch('/foobar.json', authenticityHeader(/*fetch options*/));
For safe calls (includes CSRF and credentials & same-origin header):
fetch('/foobar.json', safeCredentials(/*fetch options*/));
from react_on_rails.
We'll soon be adding a JS helper method for the CRSF to the ReactOnRails npm module for this.
We probably want to be agnostic about the choice of fetch vs. axios.
from react_on_rails.
agreed
from react_on_rails.
We simply need to add this helper method to ReactOnRails.
import _ from 'lodash';
export default {
/**
* Get CSRF Token from the DOM.
*
* @returns {String} - CSRF Token.
*/
getCSRFToken() {
const token = _.find(document.querySelectorAll('meta'), ['name', 'csrf-token']);
return token ? token.content : null;
},
};
To:
- https://github.com/shakacode/react_on_rails/blob/master/node_package%2Fsrc%2FReactOnRails.js
- A new file here: https://github.com/shakacode/react_on_rails/tree/master/node_package/src
We should also remove the dependency on lodash.
We need some docs and tests.
This gist from @fletcher91 also looks good: https://gist.github.com/fletcher91/c62b865c6aa9f710531e
from react_on_rails.
I'll probably add @fletcher91's code to the default package for ReactOnRails. Yes, we could have a separate node module. It's a tiny enough amount of code that I don't deem that necessary.
@fletcher91 Any changes to your gist? I copied below.
/**
*
* A regular non-safe get request:
* fetch('/profiles/foobar.json', jsonHeader());
*
* How this would look in a safe fetch request:
* fetch('/profiles.json', safeCredentials({
* method: 'POST',
* body: JSON.stringify({
* q: input,
* thing: this.props.thing
* })
* }));
*
*
*/
/**
* For use with window.fetch
*/
export function jsonHeader (options) {
options = options || {};
return Object.assign(options, {
'Accept': 'application/json',
'Content-Type': 'application/json'
});
}
/**
* Lets fetch include credentials in the request. This includes cookies and other possibly sensitive data.
* Note: Never use for requests across (untrusted) domains.
*/
export function safeCredentials (options) {
options = options || {};
return Object.assign(options, {
credentials: 'include',
mode: 'same-origin',
headers: Object.assign((options['headers'] || {}), authenticityHeader(), jsonHeader())
});
}
// Additional helper methods
export function authenticityHeader (options) {
options = options || {};
return Object.assign(options, {
'X-CSRF-Token': getAuthenticityToken(),
'X-Requested-With': 'XMLHttpRequest'
});
}
export function getAuthenticityToken () {
return getMetaContent('csrf-token');
}
export function getMetaContent (name) {
let header = document.querySelector(`meta[name="${name}"]`);
return header && header.content;
}
from react_on_rails.
@justin808 Aside from some minor things like let
to const
and some JSdocs, it's still the same 👍 I've updated the gist accordingly
from react_on_rails.
@fletcher91, @jbhatab does this make sense to go into React on Rails from the perspective that the CRSF thing is so standard for Rails apps? or more of a doc thing?
from react_on_rails.
@anpr With the direction were going, I think this shouldn't be covered with our gem and can be covered in a docs if even needed at all. it depends on your architecture style.
We can relook into this when we redo the docs stuff.
from react_on_rails.
@jbhatab, we're going to provide a default for this. I really think this is so common that it makes sense to include in our library, if it's non-obtrusive.
@anpr I can help you with this. Please email me at [email protected] and I can add you to our Slack room.
from react_on_rails.
We're working on restructuring our front-end (splitting into packages), so I can publish these helpers publicly to NPM if that helps
from react_on_rails.
I basically copied the code above to my project and it solved the problem (with small adjustments/additions).
Still, I see this being a common requirement, so I'd publish it either as part of the gem or as a separate npm package (I don't really care which of the two).
from react_on_rails.
@dzirtusss Please take a look at this one.
from react_on_rails.
We're using:
- https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/requestsManager.js#L33
- https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/metaTagsManager.js
and we don't have many of the headers in
https://gist.github.com/fletcher91/c62b865c6aa9f710531e
Can we abstract this into ReactOnRails?
Reference for Rails: http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf
CC: @alexfedoseev @robwise
from react_on_rails.
@fletcher91 @anpr @alexfedoseev @dphaener @samnang @dzirtusss: we'd like to know if the headers here: https://gist.github.com/fletcher91/c62b865c6aa9f710531e
should be here: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/requestsManager.js#L33
from react_on_rails.
Actually I think we should not need to include jsonHelper
into gem and specifically include json Accept
and inContent-Type
into headers
because it is already included by ??? as follows:
Content-Type: application/json;charset=UTF-8
Accept: application/json, text/plain, */*
Cookie: _rails-react-tutorial_session=...
And everything works fine.
Maybe it will not work with fetch
same way but will need to update first from axios
to isomorphic-fetch
in tutorial.
from react_on_rails.
I think it will be ok if we use fetch
like:
credentials: 'same-origin',
header: RubyOnRails.authenticityHeader(),
from react_on_rails.
Resolved by #517
from react_on_rails.
Related Issues (20)
- Change primary branch name from `master` to `main` HOT 2
- Add support for Vite
- Fix CI failure
- Server side rendering window behaves differently than Node.js? HOT 7
- React Component won't mount until all assets are loaded HOT 2
- Adjustment of Minimum Required Ruby Version for Versions 12.5.x HOT 5
- Webpacker constants still being referenced HOT 1
- Clarification and reorganization of test conditions in configuration specs HOT 2
- `react_on_rails:generate_packs` should add the import statement to the entry point even if the packs already exist
- Bump Rescript in examples due to build-time errors HOT 2
- How to refresh CSRF token? HOT 4
- uninitialized constant `ReactOnRails::Configuration::Webpacker` HOT 6
- Running `react_on_rails:install` is not compatible with Shakapacker v8 HOT 2
- Add lock file for creating packs
- Update doc for the auto bundles
- Update docs for react_router using SSR HOT 4
- Utilize shakacode/package_json for Enhanced Package Management Compatibility HOT 1
- Proposal for New CLI Tool: create-react-on-rails-app to Streamline Project Initialization
- rename master to main
- Getting `undefined method `react_component'` error with react_on_rails v12.4.0 in ruby v2.6.9 rails v6.1 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react_on_rails.